题目链接:http://poj.org/problem?id=3159
之前做过一次,然而这次又做了好久。还是不熟练啊。
spfa有时用stack比用queue快。比如这题,用queue就超时,用stack就可以过。
至于为什么好像也说不清,反正都是xjb搞出来的。。。。。。
自己稍微总结一下差分约束吧,发现不管别人写的多好,看的不管多明白,如果自己不写下来,很快就会忘。。。
理解还不够,随便写写,只是给自己巩固一下。
大神写的在这里:http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html
差分约束:
一:求最大值,转换成求最短路。
给定不等式 A-B<=C;
步骤如下:
既然是求最短路,肯定要用到过程中最重要的【松弛操作】,即
if(dis[v]>dis[u]+w) dis[v]=dis[u]+w;
这一步的目的是尽量使dis[v]<=dis[u]+w;
由此我们可把上面的不等式转化成类似的形式,即A<=B+C;(注意此处C可能是负值)
建立一条B到A边权为C的路,然后进行最短路即可。
二:求最小值,转换成求最长路。
基本和第一种相同。
不过是将不等式装换成B>=A-C;(再说一次C是带符号运算的!)
为了松弛操作时 if(dis[B]<dis[A]-C) dis[B]=dis[A]-C;
下面是本题的代码。
1 #include<cstdio> 2 #include<cstring> 3 #include<stack> 4 using namespace std; 5 const int maxn=30010; 6 const int maxe=150010; 7 const int maxx=0x3f3f3f3f; 8 int dis[maxn]; 9 int head[maxn]; 10 int ins[maxn]; 11 int cnt=0; 12 13 int n,m; 14 int u,v,w; 15 16 stack<int> sta; 17 struct edge 18 { 19 int v,w,nex; 20 }e[maxe]; 21 22 void add(int u,int v,int w) 23 { 24 e[cnt].v=v; 25 e[cnt].w=w; 26 e[cnt].nex=head[u]; 27 head[u]=cnt++; 28 } 29 30 int spfa(int s) 31 { 32 for(int i=0;i<=n;i++) 33 { 34 dis[i]=maxx; 35 ins[i]=0; 36 } 37 dis[1]=0; 38 ins[1]=1; 39 sta.push(1); 40 while(!sta.empty()) 41 { 42 int u=sta.top(); 43 sta.pop(); 44 ins[u]=0; // 45 for(int i=head[u];i!=-1;i=e[i].nex) 46 { 47 int v=e[i].v,w=e[i].w; 48 if(dis[v]>dis[u]+w) 49 { 50 dis[v]=dis[u]+w; 51 if(!ins[v]) 52 { 53 ins[v]=1; 54 sta.push(v); 55 } 56 } 57 } 58 } 59 return dis[n]; 60 } 61 int main() 62 { 63 while(scanf("%d%d",&n,&m)!=EOF) 64 { 65 cnt=0; 66 memset(head,-1,sizeof(head)); 67 for(int i=0;i<m;i++) 68 { 69 scanf("%d%d%d",&u,&v,&w); 70 add(u,v,w); 71 } 72 printf("%d ",spfa(1)); 73 } 74 }