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 }