标签:
Description
Input
Output
Sample Input
4 2 1
1 3 10
2 4 20
2 3 3
Sample Output
27
Source
正解:差分约束系统+SPFA
解题报告:
以前在codevs上面做过一道差分约束系统的题,然后就学会了这种神奇的思想。其实思想很简单,结合图论的话还是很有用的。
考虑题意,需要求1到n的最大距离。题目中给了很多限制条件,比如说x2-x1<=3,x4-x2>=6这样的条件。我们考虑像x2-x1<=3这样的条件,因为我们想让距离尽可能大,就要使距离最大化,然后建图,1向2连一条权值为3的边。那么像x4-x2>=6这样大于的怎么办呢,我们就可以把它变成x2-x4<=-6,边权为负即可。然后图上跑SPFA。
接着是个很重要的问题,是最短路还是最长路呢?按理说要想距离大应该跑最长路,但是我们想,我们这个图是怎么建的,根据每个条件的最大条件连边,那么说明我们肯定要取所有对这个点的约束中最小的那个(取交),所以只会越来越小。不难想到,最后求出的dis[n]就是我们要求的。
题意中的-1、-2怎么特判呢?如果有负权环就说明不可能,记一下每个点入队n次就说明有负权环。而可以无限大则说明还到不了n,则说明dis[n]仍为初值
轻松AC,代码如下:
1 //It is made by jump~ 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <ctime> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #ifdef WIN32 13 #define OT "%I64d" 14 #else 15 #define OT "%lld" 16 #endif 17 using namespace std; 18 typedef long long LL; 19 const int MAXN = 100011; 20 const int MAXM = 400011; 21 const int inf = (1<<30); 22 int n,m1,m2; 23 int first[MAXN],to[MAXM],next[MAXM],w[MAXM],ecnt; 24 int dis[MAXN]; 25 queue<int>Q; 26 bool pd[MAXN]; 27 int cnt[MAXN]; 28 29 inline int getint() 30 { 31 int w=0,q=0; 32 char c=getchar(); 33 while((c<‘0‘ || c>‘9‘) && c!=‘-‘) c=getchar(); 34 if (c==‘-‘) q=1, c=getchar(); 35 while (c>=‘0‘ && c<=‘9‘) w=w*10+c-‘0‘, c=getchar(); 36 return q ? -w : w; 37 } 38 39 inline void link(int x,int y,int z){ 40 next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; w[ecnt]=z; 41 } 42 43 inline bool spfa(){ 44 Q.push(1); pd[1]=1; 45 for(int i=2;i<=n;i++) dis[i]=inf; 46 while(!Q.empty()){ 47 int u=Q.front(); Q.pop(); pd[u]=0; 48 for(int i=first[u];i;i=next[i]) { 49 int v=to[i]; 50 if(dis[v]>dis[u]+w[i]) { 51 dis[v]=dis[u]+w[i]; 52 if(!pd[v]) { 53 Q.push(v); 54 pd[v]=1; 55 cnt[v]++; 56 if(cnt[v]>=n) return false; 57 } 58 } 59 } 60 } 61 if(dis[n]==inf) printf("-2"); 62 else printf("%d",dis[n]); 63 return true; 64 } 65 66 inline void solve(){ 67 n=getint(); m1=getint(); m2=getint(); 68 int x,y,z; 69 for(int i=1;i<=m1;i++) { 70 x=getint();y=getint();z=getint(); 71 link(x,y,z); 72 } 73 for(int i=1;i<=m2;i++) { 74 x=getint(); y=getint(); z=getint(); 75 link(y,x,-z); 76 } 77 if(!spfa()) printf("-1"); 78 } 79 80 int main() 81 { 82 solve(); 83 return 0; 84 }
标签:
原文地址:http://www.cnblogs.com/ljh2000-jump/p/5540630.html