标签:拓扑排序
Connected Caves |
Time Limit: 2000ms, Special Time Limit:5000ms, Memory Limit:65536KB |
Total submit users: 6, Accepted users: 5 |
Problem 13247 : Special judge |
Problem description |
You’re an intern at Greedy Cave Plundering Corporation. Your new job is to help with one of GCPC’s projects: extracting valuable gemstones from a network of connected caves. The history of the project so far: |
Input |
The input starts with a line containing T, the number of test cases (1 ≤ T ≤ 10). Each test case starts with a line containing two integers: N, the number of caves, and E, the number of passage ways (1 ≤ N ≤ 2 · 10^4; 0 ≤ E ≤ 10^5). The second line contains N integers v1 v2... vN. videscribes the value of all gemstones in cave i (0 ≤ vi≤ 10^4). Each of the next E lines contains three integers: a e b e c e . Such a line represents one of the possible direct passage ways from cave a e to cave b e , widening this passage way will cost c e (1 ≤ a e ,b e ≤ N; 0 ≤ c e ≤ 10^4). It is guaranteed that the input contains only valid digging directions, i.e. cave b e will be strictly deeper than a e . You always start from cave number 1, because the digging machine is already there and there are no caves above. |
Output |
Output two lines for every test case. In the first line print two integers P and C, where P is the profit of the best possible route from top to bottom and C is the number of visited caves on that path. In the second line print the IDs of those caves, ordered from top to bottom. If there are multiple solutions with optimal profit, print any. |
Sample Input |
3 1 0 10 4 3 10 20 30 40 1 2 19 1 3 23 1 4 34 4 4 10 20 30 40 1 2 10 2 4 20 1 3 20 3 4 10 |
Sample Output |
10 1 1 17 2 1 3 50 3 1 3 4 |
Problem Source |
GCPC 2014
题意:给出n个点1~n,m条边,每个点有一个价值,给出的每条边是有向边a-->b 花费c,无环图,得到的总价值= 走过的点的价值和-走过边的花费。从点1开始走,问最大能得多少价值。有多少个点,都有哪些点组成。 解题:就用拓扑序列做。须自写scanf函数,否则超时。 #include<stdio.h> #include<vector> using namespace std; #define LL int const int N = 20005; #define inf -600000000 struct TO { int v; LL c; }; LL node[N],valu[N]; int fath[N],n,in[N]; vector<TO>tmap[N]; void init() { for(int i=1; i<=n;i++) { in[i]=0; node[i]=inf; tmap[i].clear(); } } void topu() { int k,to[N],id; LL sum; k=0; for(int i=2;i<=n;i++) if(!in[i]) to[++k]=i; while(k) { int s=to[k]; k--; for(int i=0;i<tmap[s].size();i++) { int v=tmap[s][i].v; in[v]--; if(in[v]==0) to[++k]=v; } } to[++k]=1; node[1]=valu[1]; fath[1]=1; sum=node[1],id=1; while(k) { int s=to[k]; k--; for(int i=0;i<tmap[s].size();i++) { int v=tmap[s][i].v; in[v]--; if(in[v]==0) to[++k]=v; if(node[v]<node[s]+valu[v]-tmap[s][i].c) node[v]=node[s]+valu[v]-tmap[s][i].c,fath[v]=s; if(sum<node[v]) sum=node[v],id=v; } } k=0; while(fath[id]!=id) { to[++k]=id; id=fath[id]; } to[++k]=id; printf("%d %d\n%d",sum,k,to[k]); for(int i=k-1; i>0; i--) printf(" %d",to[i]); printf("\n"); } inline void scanf(int &a) { int flag=0; char ch; while(ch=getchar()) { if(ch=='-') { flag=1; break; } if(ch>='0'&&ch<='9') break; } a=0; if(flag==0) a=ch-'0'; while(ch=getchar()) { if(ch<'0'||ch>'9') break; a=a*10+ch-'0'; } if(flag) a=-a; } int main() { int t,m,a,b,c; scanf(t); while(t--) { scanf(n); scanf(m); init(); for(int i=1;i<=n;i++) scanf(valu[i]); TO ss; while(m--) { scanf(a); scanf(ss.v); scanf(ss.c); if(a==ss.v) continue; tmap[a].push_back(ss); in[ss.v]++; } topu(); } } |
标签:拓扑排序
原文地址:http://blog.csdn.net/u010372095/article/details/44517249