P2648 赚钱
对于不知道起点在哪里的最短路,先建立一个超级源点,然后从超级源点跑最长路,并判正环即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cmath> 6 #include<ctime> 7 #include<set> 8 #include<cstring> 9 #define inf 2147483647 10 #define For(i,a,b) for(register int i=a;i<=b;i++) 11 #define p(a) putchar(a) 12 #define g() getchar() 13 //by war 14 //2017.20.27 15 using namespace std; 16 struct node 17 { 18 int n,v; 19 node *next; 20 }*e[100000]; 21 int D,P,C,F; 22 int x,y,z; 23 queue<int>q; 24 bool vis[10010]; 25 int d[1010]; 26 int t; 27 int cnt[10010]; 28 int ans=-inf; 29 void in(int &x) 30 { 31 int y=1; 32 char c=g();x=0; 33 while(c<'0'||c>'9') 34 { 35 if(c=='-') 36 y=-1; 37 c=g(); 38 } 39 while(c<='9'&&c>='0')x=x*10+c-'0',c=g(); 40 x*=y; 41 } 42 void o(int x) 43 { 44 if(x<0) 45 { 46 p('-'); 47 x=-x; 48 } 49 if(x>9)o(x/10); 50 p(x%10+'0'); 51 } 52 53 void push(int x,int y,int v) 54 { 55 node *p; 56 p=new node(); 57 p->n=y; 58 p->v=v; 59 if(e[x]==NULL) 60 e[x]=p; 61 else 62 { 63 p->next=e[x]->next; 64 e[x]->next=p; 65 } 66 } 67 68 void spfa(int x) 69 { 70 node *p; 71 For(i,1,C) 72 d[i]=-inf; 73 q.push(x); 74 cnt[x]++; 75 while(q.size()>0) 76 { 77 t=q.front(); 78 vis[t]=true; 79 p=e[t]; 80 while(p!=NULL) 81 { 82 if(d[t]+p->v>d[p->n]) 83 { 84 d[p->n]=d[t]+p->v; 85 if(!vis[p->n]) 86 { 87 q.push(p->n); 88 cnt[p->n]++; 89 if(cnt[p->n]>C) 90 { 91 puts("orz"); 92 exit(0); 93 } 94 vis[p->n]=true; 95 } 96 } 97 p=p->next; 98 } 99 vis[t]=false; 100 q.pop(); 101 } 102 } 103 104 int main() 105 { 106 in(D),in(P),in(C),in(F); 107 For(i,1,C) 108 push(0,i,D); 109 110 For(i,1,P) 111 { 112 in(x),in(y); 113 push(x,y,D); 114 } 115 For(i,1,F) 116 { 117 in(x),in(y),in(z); 118 push(x,y,D-z); 119 } 120 spfa(0); 121 For(i,1,C) 122 ans=max(ans,d[i]); 123 o(ans); 124 return 0; 125 }