UESTC 1511(差分约束)
题目链接:http://acm.uestc.edu.cn/problem.php?pid=1511
思路:我们可以等到这样的5个关系式:
k=1:dsit[a]-dist[b]>=0&&dist[b]-dist[a]>=0
k=2:dist[a]-dist[b]<=-1;
k=3:dist[a]-dist[b]>=0;
k=4:dist[a]-dist[b]>=1;
k=5:dist[a]-dist[b]<=0;
然后就是spfa求最长路了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define MAXN 100200 8 #define inf 1<<30 9 10 struct Edge{ 11 int v,w; 12 Edge(int vv,int ww):v(vv),w(ww){} 13 }; 14 15 int n,m,NE; 16 17 int head[MAXN]; 18 vector<vector<Edge> >g; 19 20 void Insert(int u,int v,int w) 21 { 22 g[u].push_back(Edge(v,w)); 23 } 24 25 int dist[MAXN]; 26 bool mark[MAXN]; 27 int _count[MAXN]; 28 29 long long spfa(int vs) 30 { 31 memset(mark,false,(n+2)*sizeof(bool)); 32 memset(_count,0,(n+2)*sizeof(int)); 33 fill(dist,dist+n+4,-inf); 34 dist[vs]=0; 35 queue<int>que; 36 que.push(vs); 37 while(!que.empty()){ 38 int u=que.front(); 39 que.pop(); 40 mark[u]=false; 41 _count[u]++; 42 if(_count[u]>n)return -1; 43 for(int i=0;i<g[u].size();i++){ 44 int v=g[u][i].v,w=g[u][i].w; 45 if(dist[u]+w>dist[v]){ 46 dist[v]=dist[u]+w; 47 if(!mark[v]){ 48 mark[v]=true; 49 que.push(v); 50 } 51 } 52 } 53 } 54 long long ans=0; 55 for(int i=1;i<=n;i++){ 56 ans+=dist[i]; 57 } 58 return ans; 59 } 60 61 int main() 62 { 63 int k,u,v,flag; 64 while(~scanf("%d%d",&n,&m)){ 65 NE=0; 66 memset(head,-1,(n+2)*sizeof(int)); 67 flag=0; 68 g.clear(); 69 g.resize(n+2); 70 while(m--){ 71 scanf("%d%d%d",&k,&u,&v); 72 if(k==1){ 73 Insert(u,v,0); 74 Insert(v,u,0); 75 }else if(k==2){ 76 Insert(u,v,1); 77 if(u==v)flag=1; 78 }else if(k==3){ 79 Insert(v,u,0); 80 }else if(k==4){ 81 Insert(v,u,1); 82 if(u==v)flag=1; 83 }else if(k==5){ 84 Insert(u,v,0); 85 } 86 } 87 for(int i=1;i<=n;i++){ 88 Insert(0,i,1); 89 } 90 if(flag){ 91 puts("-1"); 92 continue; 93 } 94 printf("%lld\n",spfa(0)); 95 } 96 return 0; 97 }