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)
",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
");
64     else if(d[1]==inf)  printf("-2
");
65     else    printf("%d
",d[1]);
66  //   for(int i=1;i<=N;i++)   printf("%d
",d[i]);
67     return 0;
68 }
View Code
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
原文地址:https://www.cnblogs.com/Blogggggg/p/7259870.html