【链接】
bzoj2330
【解题报告】
差分约束系统裸题。不会可以去看百科。
Ps:注意加一个点会T。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=100005,maxm=300005;
int n,m,tot,dst[maxn],num[maxn],que[maxn],lnk[maxn],son[maxm],nxt[maxm];
bool vis[maxn],w[maxm];
LL ans;
inline char nc()
{
static char buf[100000],*l,*r;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
if (l==r) return EOF; return *l++;
}
inline int Read()
{
int res=0; char ch=nc();
while (ch<'0'||ch>'9') ch=nc();
while (ch>='0'&&ch<='9') res=res*10+ch-48,ch=nc();
return res;
}
void Add(int x,int y,bool z) {w[++tot]=z; son[tot]=y; nxt[tot]=lnk[x]; lnk[x]=tot;}
bool Spfa()
{
memset(num,0,sizeof(num));
int hed=0,til=0;
for (int i=1; i<=n; i++) que[til=(til+1)%maxn]=i,vis[i]=1,dst[i]=1;
while (hed!=til)
{
int x=que[hed=(hed+1)%maxn]; vis[x]=0;
for (int j=lnk[x]; j; j=nxt[j])
if (dst[x]+w[j]>dst[son[j]])
{
if (++num[son[j]]>=n) return 0;
dst[son[j]]=dst[x]+w[j];
if (!vis[son[j]])
{
que[til=(til+1)%maxn]=son[j]; vis[son[j]]=1;
if (dst[que[til]]>dst[que[(hed+1)%maxn]]) swap(que[til],que[(hed+1)%maxn]);
}
}
}
return 1;
}
int main()
{
freopen("2330.in","r",stdin);
freopen("2330.out","w",stdout);
n=Read(); m=Read(); tot=0;
memset(lnk,0,sizeof(lnk));
for (int i=1; i<=m; i++)
{
int x=Read(),a=Read(),b=Read();
switch (x)
{
case 1:Add(a,b,0);Add(b,a,0);break;
case 2:if (a==b) {printf("-1"); return 0;}
Add(a,b,1);break;
case 3:Add(b,a,0);break;
case 4:if (a==b) {printf("-1"); return 0;}
Add(b,a,1);break;
case 5:Add(a,b,0);break;
}
}
if (!Spfa()) {printf("-1"); return 0;}
ans=0; for (int i=1; i<=n; i++) ans+=dst[i];
printf("%lld\n",ans);
return 0;
}