查分约束例题(洛古)
昨天看了看差分约束系统的算法。。。做了4道题。。。
#include<iostream> #include<algorithm> #include<queue> #include<vector> struct edge{ int to,w; }; using namespace std; const int maxm=100010,maxn=30010,inf=99999999; int s[maxm],t[maxm],w[maxm],cnt=0,n,dis[maxn]; vector<edge>map[maxn]; void add_edge(int a,int b,int c){ map[a].push_back((edge){b,c}); } bool book[maxn]; void spfa(int st){ queue<int>q; q.push(st); for(int i=0;i<=n;++i)dis[i]=-inf; dis[st]=0; book[st]=1; while(!q.empty()){ int t=q.front(); q.pop(); book[t]=0; for(int i=0;i<map[t].size();++i){ if(dis[t]!=-inf&&dis[map[t][i].to]<dis[t]+map[t][i].w){ dis[map[t][i].to]=dis[t]+map[t][i].w; if(!book[map[t][i].to]){ book[map[t][i].to]=1; q.push(map[t][i].to); } } } } } int main(){ int m; cin>>n>>m; for(int i=0;i<n;++i){ add_edge(i,i+1,0); add_edge(i+1,i,-1); } for(int i=1;i<=m;++i){ int a,b,c; cin>>a>>b>>c; add_edge(a-1,b,c); } for(int i=0;i<=n;++i)add_edge(n+1,i,0); spfa(n+1); for(int i=1;i<=n;++i){ for(int j=1;j<=cnt;++j){ if(dis[s[j]]!=-inf&&dis[s[j]]+w[j]>dis[t[j]]){ dis[t[j]]=dis[s[j]]+w[j]; } } } cout<<dis[n]; return 0; }
#include<iostream> #include<algorithm> #include<queue> #include<vector> using namespace std; const int maxn=10010,inf=99999999; struct edge{ int to,w; }; int n,dis[maxn]; vector<edge>map[maxn]; void add_edge(int a,int b,int c){ map[a].push_back((edge){b,c}); } bool book[maxn]; bool spfa(int st){ for(int i=1;i<=n;++i)dis[i]=inf; book[st]=1; queue<int>q; q.push(st); int cnt=0; while(!q.empty()){ int t=q.front(); book[t]=0; q.pop(); for(int i=0;i<map[t].size();++i){ if(dis[t]!=inf&&dis[map[t][i].to]>dis[t]+map[t][i].w){ if(book[map[t][i].to]){ return 0; } dis[map[t][i].to]=dis[t]+map[t][i].w; book[map[t][i].to]=1; q.push(map[t][i].to); } } } return 1; } int main(){ int m; cin>>n>>m; for(int i=1;i<=m;++i){ int k,s,t,w; cin>>k>>s>>t; if(k==1){ cin>>w; add_edge(s,t,w); } else if(k==2){ cin>>w; add_edge(t,s,-w); } else{ add_edge(s,t,0); add_edge(t,s,0); } } for(int i=1;i<=n;++i)add_edge(n+1,i,0); if(spfa(n+1))cout<<"Yes"; else cout<<"No"; return 0; }
#include<iostream> #include<algorithm> #include<cstring> using namespace std; const int maxm=5010,inf=99999999; int s[maxm],t[maxm],w[maxm],dis[110],cnt=0; void add_edge(int a,int b,int c){ s[++cnt]=a; t[cnt]=b; w[cnt]=c; } int main(){ int T; cin>>T; while(T--){ int n,m; cin>>n>>m; cnt=0; memset(dis,0,sizeof(dis)); for(int i=1;i<=m;++i){ int s,t,w; cin>>s>>t>>w; add_edge(s-1,t,w); add_edge(t,s-1,-w); } bool flag=0; for(int i=0;i<=n;++i)add_edge(n+1,i,0); dis[n+1]=0; for(int i=1;i<=n+1;++i){ for(int j=1;j<=cnt;++j){ if(dis[s[j]]!=inf&&dis[t[j]]>dis[s[j]]+w[j]){ dis[t[j]]=dis[s[j]]+w[j]; if(i>=n+1)flag=1; } } } if(flag)cout<<"false"; else cout<<"true"; cout<<endl; } return 0; }
#include <bits/stdc++.h> using namespace std; const int N = 1e5+5; struct node { int v,w,next; } d[N*2]; int tot,front[N],n,k; long long ans; int dis[N],vis[N],use[N]; queue <int> q; void add(int u,int v,int w) { d[++tot].v = v; d[tot].w = w; d[tot].next = front[u]; front[u] = tot; } bool spfa() { while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; use[u] = 0; for(int i=front[u]; i; i=d[i].next) { int v = d[i].v, w = d[i].w; if(dis[v] < dis[u] + w) { dis[v] = dis[u] +w; use[i]++; if(use[i]>n-1) return false; if(!vis[v]) { vis[v] = 1; q.push(v); } } } } return true; } int main() { scanf("%d %d",&n,&k); for(int i=1; i<=k; i++) { int op,u,v; scanf("%d %d %d",&op,&u,&v); if(op==1) { add(u,v,0); add(v,u,0); } if(op==2) add(u,v,1); if(op==3) add(v,u,0); if(op==4) add(v,u,1); if(op==5) add(u,v,0); if(op%2==0 && u==v) { printf("-1\n"); return 0; } } for(int i=1; i<=n; i++) { vis[i] = 1; dis[i] = 1; use[i] = 1; q.push(i); } if(!spfa()) { printf("-1\n"); return 0; } for(int i=1; i<=n; i++) ans+=dis[i]; printf("%lld\n",ans); return 0; }