#include<bits/stdc++.h>usingnamespace std;constint N =3e5+10;typedeflonglong ll;typedef pair<int,int>PII;//spfa判断负环
vector<PII>ed[N];int dis[N];int st[N];int n, m, w;int cnt[N];boolspfa(){memset(dis,0x3f,sizeof dis);memset(cnt,0,sizeof cnt);memset(st,0,sizeof st);
dis[1]=0;
queue<int>q;for(int i =1; i <= n; i ++){
q.push(i);//因为起点不确定,因此需要都压入}
cnt[1]++;while(q.size()){int x = q.front();
q.pop();
st[x]=0;for(auto it : ed[x]){if(dis[it.first]<= dis[x]+ it.second)continue;
dis[it.first]= dis[x]+ it.second;if(!st[it.first]){
cnt[it.first]++;
st[it.first]=1;
q.push(it.first);if(cnt[it.first]>= n)returntrue;}}}returnfalse;}intmain(){int t;
cin >> t;while(t --){
cin >> n >> m >> w;for(int i =0; i < m; i ++){int a, b, c;
cin >> a >> b >> c;
ed[a].push_back({b, c});
ed[b].push_back({a, c});}for(int i =0; i < w; i ++){int a, b, c;
cin >> a >> b >> c;
ed[a].push_back({b,-c});}//建图if(spfa())puts("YES");elseputs("NO");for(int i =0; i <= n *2; i ++) ed[i].clear();}return0;}
差分约束:
思路:
AC代码:
#include<iostream>#include<cstring>typedeflonglong LL;constint N =1e5+10, M =3* N;int n, m;int h[N], e[M], w[M], ne[M], idx;int dist[N], cnt[N], q[N];bool st[N];voidadd(int a,int b,int c){
e[idx]= b, w[idx]= c, ne[idx]= h[a], h[a]= idx++;}boolspfa(){//因为是求所有x_i的最小值,因此就是求不等式的下界的最大值//转而就是求图论的最长路int hh =0, tt =1;memset(dist,-0x3f,sizeof dist);
dist[0]=0;
q[0]=0;//建立一个能够到所有点的虚拟源点0for(int i =1; i <= n;++i)add(0, i,1);//x_0 <= x_i + 1//这题在判负环的时候会TLE//上一次的“负环”题目中的trick方法还是太玄学了//这里用一个不会TLE的判负环方法,那就是把SPFA算法中的循环队列改为栈//这样对于遇到的负环,就不会加入队尾,知道再次遍历完整个队列才去算他//遇到负环会直接在栈顶连续入栈出栈,直到判断他的cnt[i] >= n+1,即发现负环while(hh != tt){int t = q[--tt];
st[t]=false;for(int i = h[t];~i; i = ne[i]){int j = e[i];if(dist[j]< dist[t]+ w[i]){
dist[j]= dist[t]+ w[i];
cnt[j]= cnt[t]+1;if(cnt[j]>= n +1)returntrue;if(!st[j]){
st[j]=true;
q[tt++]= j;}}}}returnfalse;}intmain(){memset(h,-1,sizeof h);scanf("%d%d",&n,&m);while(m--){int x, a, b;scanf("%d%d%d",&x,&a,&b);if(x ==1)add(a, b,0),add(b, a,0);elseif(x ==2)add(a, b,1);elseif(x ==3)add(b, a,0);elseif(x ==4)add(b, a,1);elseif(x ==5)add(a, b,0);}if(spfa())puts("-1");else{
LL res =0;for(int i =1; i <= n;++i) res += dist[i];printf("%lld\n", res);}return0;}