标签:不同的 大量 pac ret string -- show har void
对于一个刚接触差分约束系统的OIer来说,这算是一道细节比较多,也比较难的题。首先就是这道题有5种不同的约束条件,对于条件1,3,5直接按照差分条件建边即可,条件2,4要先移项,再建边。之后再求单源最长路,好不容易做出来后你就会发现数据卡SPFA!!!!这里可以加两个小小的优化:1)当a,b严格大于或小于时,他们不能为同一个人,先预判出来可以节省大量时间(不加#5会TLE)。还有要倒序建边,,,(没有任何道理,倒序就能AC,正序会TLE)
参考程序如下:
#include<iostream> #include<cstring> #include<queue> #include<cstdio> using namespace std; long long n,m,dist[350005],v[350005],w[350005],nxt[350005],head[350005],cnt,x,a,b,ring[350005]; bool vis[350005]; inline int read() { int f=1,x=0; char s=getchar(); while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();} while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();} return x*f; } inline void add(int a,int b,int c) { v[++cnt]=b; w[cnt]=c; nxt[cnt]=head[a]; head[a]=cnt; } inline bool spfa(int node) { queue<int>q; q.push(node); vis[node]=1; while(!q.empty()) { int c=q.front(); q.pop(); vis[c]=0; ring[c]++; //cout<<c<<endl; if(ring[c]==n)return 0; for(int i=head[c];i;i=nxt[i]) { int y=v[i]; //cout<<"-------------------CJXGBH---------------------"<<endl; //cout<<dist[y]<<" "<<dist[c]<<" "<<w[i]<<endl; if(dist[y]<dist[c]+w[i]) { dist[y]=dist[c]+w[i]; if(!vis[y]) { q.push(y); vis[y]=1; } } } } return 1; } int main() { //freopen("1.in","r",stdin); n=read();m=read(); for(int i=1;i<=m;i++) { x=read();a=read();b=read(); if(x==1) { add(a,b,0); add(b,a,0); } if(x==2) { add(a,b,1); if(a==b) { cout<<"-1"; return 0; } } if(x==3) { add(b,a,0); } if(x==4) { add(b,a,1); if(a==b) { cout<<"-1"; return 0; } } if(x==5) { add(a,b,0); } } for(int i=n;i>=1;i--) { add(0,i,1); } if(!spfa(0)) { cout<<"-1"; return 0; } long long ans=0; for(int i=1;i<=n;i++)ans+=dist[i]; cout<<ans; return 0; }
标签:不同的 大量 pac ret string -- show har void
原文地址:https://www.cnblogs.com/szmssf/p/11079874.html