传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2330
一直以为差分约束系统很神……然后学了它……
求最大值跑最短路,求最小值跑最长路(我也不知道为什么)
如果有x-y>=z 连边 y->x w = z (最长路) x->y w=-z (最短路)
超级源点连所有点w=0,这道题似乎是说每个人至少有一个糖果……所以此题源点的dis值是1
Code:
#include<cstdio>
#include<cmath>
#include<vector>
#include<climits>
#include<queue>
#include<stack>
#include<cstring>
#include<iostream>
#include<algorithm>
#define V first
#define W second
using namespace std;
const int maxn=1e5+10;
typedef long long lld;
typedef pair<lld,lld> pii;
namespace TOPL{
vector<pii>G[maxn];
lld d[maxn];
lld in[maxn],vis[maxn];
void add(lld u,lld v,lld w){
G[u].push_back(pii(v,w));
}lld n,m;
void init(){
scanf("%lld%lld",&n,&m);
for(lld i=1;i<=m;i++){
lld opt;scanf("%lld",&opt);
lld x,y;scanf("%lld%lld",&x,&y);
switch(opt){
case 1:{
add(x,y,0);
add(y,x,0);
break;
}
case 2:{
add(x,y,1);
break;
}
case 3:{
add(y,x,0);
break;
}
case 4:{
add(y,x,1);
break;
}
case 5:{
add(x,y,0);
break;
}
}
}
for(lld i=1;i<=n;i++)
add(0,i,0);
}
lld solve(){
init();
queue<lld>q;
memset(d,0xaf,sizeof(d));
d[0]=1;
q.push(0);
while(!q.empty()){
lld u=q.front();q.pop();vis[u]=0;
for(lld i=0;i<G[u].size();i++){
lld v=G[u][i].V,w=G[u][i].W;
if(d[v]<d[u]+w){
d[v]=d[u]+w;
if(!vis[v]){
vis[v]=1;
q.push(v);
in[v]++;
if(in[v]>=100){
puts("-1");
return 0;
}
}
}
}
}
lld ans=0;
for(int i=1;i<=n;i++)
ans+=d[i];
cout<<ans<<endl;
return 0;
}
}
int main(){
// freopen("candy5.in","r",stdin);
return TOPL::solve();
}