POJ3169
题目链接:http://poj.org/problem?id=3169
AC思路:
spfa算法。
设各牛的位置为x[ ]。
对于感情好的牛,即第2到ML+1行:A B D, 有x[B] - x[A] <=D.而对于感情不好的牛,即第ML+2到ML+MD+1行: A B D, 则有x[B] - x[A] >=D,可以转化为x[A] - x[B] <= -D.
这是一个差分约束题,第一类式子x[B] - x[A] <=D可以看成是从点B到点A的边权为D,而第二类式子也可以转换成x[A] - x[B] <= -D,看成是从点A到点B的负权边。
最终目的是要求 x[N] - x[1]的最大值,其实就是从N点出发到 1点的单源最短路问题。理解了差分约束这个概念,这道题就不难了。
AC代码:
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxv=1000+3,maxe=20000+3; 6 const int inf=0x7ffffff; 7 int edgecount,N; 8 int head[maxv],d[maxv],visitcount[maxv]; 9 bool inq[maxv]; 10 queue<pair<int,int> > q; 11 struct edge{ 12 int from,to,val,next; 13 edge(){} 14 edge(int _f,int _t,int _v,int _n){ 15 from=_f,to=_t,val=_v,next=_n; 16 } 17 }es[maxe]; 18 void addedge(int from,int to,int val){ 19 es[edgecount]=edge(from,to,val,head[from]); 20 // printf("es[%d] = (%d,%d,%d,%d)\n",edgecount,from,to,val,head[from]); 21 head[from]=edgecount++; 22 } 23 bool spfa(int s){ 24 for(int i=1;i<=N;i++){ 25 d[i]=inf; 26 inq[i]=(i==s); 27 visitcount[i]=0; 28 } 29 d[s]=0; 30 q.push(make_pair(d[s],s)); 31 while(!q.empty()){ 32 int dist=q.front().first,u=q.front().second; 33 q.pop(); 34 inq[u]=false; 35 if(visitcount[u]++>N) return true; 36 for(int e=head[u];e!=-1;e=es[e].next){ 37 int t=es[e].to,value=es[e].val; 38 if(d[t]>d[u]+value){ 39 d[t]=d[u]+value; 40 if(!inq[t]){ 41 inq[t]=true; 42 q.push(make_pair(d[t],t)); 43 } 44 } 45 } 46 } 47 return false; 48 } 49 int main() 50 { 51 memset(head,-1,sizeof(head)); 52 int ML,MD,A,B,D; edgecount=0; 53 scanf("%d%d%d",&N,&ML,&MD); 54 while(ML--){ 55 scanf("%d%d%d",&A,&B,&D); 56 addedge(B,A,D); 57 } 58 while(MD--){ 59 scanf("%d%d%d",&A,&B,&D); 60 addedge(A,B,-D); 61 } 62 63 if(spfa(N)) printf("-1\n"); 64 else if(d[1]==inf) printf("-2\n"); 65 else printf("%d\n",d[1]); 66 // for(int i=1;i<=N;i++) printf("%d\n",d[i]); 67 return 0; 68 }
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”