xdoj 1025ios
題目分析:看着好嚇人啊。。其實分析清晰也很簡單。每種物體既能夠直接買到或者由其餘物體制做獲得。那麼咱們就取二者的最小值。製做的花費咱們能夠這樣求得
若是x的原材料有y 那麼x和y之間有一條有向邊 。而後按照拓撲排序的順序自底而上求出各個物體制做所需的價值。。很簡單嗎?!
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <vector> 6 using namespace std; 7 const int N=1e4+7; 8 vector < vector <int> > g(N); 9 int val[N]; 10 bool vis[N]; 11 int n,m,w; 12 void dfs (int rt) { 13 vis[rt]=1; 14 if (g[rt].size()==0) return ;// 最底層直接返回 15 int cost=w; 16 for (int i=0;i<g[rt].size();i++) { 17 int next=g[rt][i]; 18 if (!vis[next]) dfs(next); 19 cost+=val[next];//cost製做費用 20 } 21 val[rt]=min (cost,val[rt]);//取二者最小值 22 return ; 23 } 24 int main () 25 { 26 int T; 27 scanf ("%d",&T); 28 while (T--) { 29 scanf ("%d %d %d",&n,&m,&w); 30 for (int i=0;i<n;i++) g[i].clear(); 31 memset (vis,0,sizeof(vis)); 32 for (int i=0;i<n;i++) { 33 scanf ("%d",&val[i]); 34 int num; scanf ("%d",&num); 35 for (int j=0;j<num;j++) { 36 int u; scanf ("%d",&u); 37 g[i].push_back(u); 38 } 39 } 40 for (int i=0;i<n;i++) 41 if (!vis[i]) dfs (i); 42 int sum=0; 43 for (int i=0;i<m;i++) { 44 int x; scanf ("%d",&x); 45 sum+=val[x]; 46 } 47 printf ("%d\n",sum); 48 } 49 return 0; 50 }
ccf 高速公路 求聯通份量 這個算法好像叫trajin 向這些科學家致敬算法
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <stack> 5 #include <vector> 6 using namespace std; 7 const int N=1e4+7; 8 vector < vector <int> > g(N); 9 stack <int> ss; 10 bool instack[N]; 11 bool vis[N]; 12 int dfn[N],low[N];// dfn 保存遍歷序號 low 這個點所能到達的最小點 13 int ans; 14 int n,m; 15 int cnt;//訪問順序 16 void dfs (int rt) { 17 vis[rt]=1; 18 instack[rt]=1; ss.push(rt); 19 dfn[rt]=low[rt]=++cnt; 20 for (int i=0;i<g[rt].size();i++) { 21 int next=g[rt][i]; 22 if (!vis[next]) { 23 dfs (next); 24 low[rt]=min (low[rt],low[next]); 25 } 26 else if (instack[next]) { 27 low[rt]=min (low[rt],low[next]); 28 } 29 } 30 if (dfn[rt]==low[rt]) {// dfn[rt]==low[rt] 表示遍歷一個聯通分變量啦 31 int num=1; 32 int tmp=ss.top(); ss.pop(); instack[tmp]=0;//在棧中 說明這個點的後繼子孫尚未訪問完 33 while (dfn[tmp]!=low[tmp]) { num++; tmp=ss.top(); ss.pop(); instack[tmp]=0;} 34 ans+=(num-1)*num/2; 35 } 36 return ; 37 } 38 int main () 39 { 40 ios::sync_with_stdio(false); 41 cin>>n>>m; 42 for (int i=1;i<=m;i++) { 43 int x,y; cin>>x>>y; 44 g[x].push_back(y); 45 } 46 for (int i=1;i<=n;i++) 47 if (!vis[i]) dfs (i); 48 printf ("%d\n",ans); 49 return 0; 50 }