关系运算图(差分约束)
差分约束:
用<=来构图(遵循向量的性质),找最小值,用最长路
一开始全部入队(假定图联通),然后用spfa来跑最长路
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
int n,m,times[1009];
int num[10009*2],nxt[10009*2],head[1009],cnt=0,team[1000009],dis[1009],cost[10009*2];
bool f[1009];
void add(int a,int b,int p)
{
cnt++;
num[cnt]=b;
nxt[cnt]=head[a];
head[a]=cnt;
cost[cnt]=p;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,b,p;
scanf("%d%d%d",&a,&b,&p);
if(p==1) add(b,a,1);
if(p==-1) add(a,b,1);
if(p==0) add(a,b,0),add(b,a,0);
}
int head1=0,tail=0;
for(int i=1;i<=n;i++)
{
team[++tail]=i;
f[i]=true;
times[i]=1;
}
while(head1<tail)
{
int k=team[++head1];
f[k]=false;
for(int i=head[k];i;i=nxt[i])
{
int v=num[i];
if(dis[v]<dis[k]+cost[i])
{
dis[v]=dis[k]+cost[i];
if(!f[v])
{
team[++tail]=v;
f[v]=true;
times[v]++;
if(times[v]>n)
{
printf("NO\n");
return 0;
}
}
}
}
}
int k=-1;
for(int i=1;i<=n;i++)
{
if(k<dis[i]) k=dis[i];
}
printf("%d",k);
return 0;
}