开学了,不能愉快地刷题了QAQ
差分约束(以前用并查集做真是作死。。)然后有个点比较坑,要过的话就要倒着加边,否则TLE
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(int i=l;i<=r;i++) 3 #define dec(i,l,r) for(int i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define lowbit(x) (x&(-x)) 10 #define NM 200000+5 11 using namespace std; 12 int read(){ 13 int x=0,f=1;char ch=getchar(); 14 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 15 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 16 return x*f; 17 } 18 struct edge{ 19 int t,v; 20 edge *next; 21 }e[2*NM],*h[NM],*o=e; 22 void add(int x,int y,int v){ 23 o->t=y;o->v=v;o->next=h[x];h[x]=o++; 24 } 25 int n,m,_x,_y,_t,d[NM],cnt[NM]; 26 ll s; 27 bool v[NM]; 28 queue<int >q; 29 bool spfa(){ 30 v[0]++;q.push(0); 31 while(!q.empty()){ 32 int t=q.front();q.pop();v[t]=false; 33 if(cnt[t]>=n)return 0; 34 link(t)if(d[j->t]<d[t]+j->v){ 35 d[j->t]=d[t]+j->v; 36 if(++cnt[j->t]>=n)return 0; 37 if(!v[j->t])v[j->t]++,q.push(j->t); 38 } 39 } 40 return 1; 41 } 42 int main(){ 43 n=read();m=read(); 44 while(m--){ 45 _t=read();_x=read();_y=read(); 46 if(_t==1)add(_x,_y,0),add(_y,_x,0); 47 else if(_t==2)add(_x,_y,1); 48 else if(_t==3)add(_y,_x,0); 49 else if(_t==4)add(_y,_x,1); 50 else add(_x,_y,0); 51 if((_t==2||_t==4)&&_x==_y){ 52 printf("-1\n");return 0; 53 } 54 } 55 dec(i,n,1)add(0,i,1); 56 if(!spfa()){ 57 printf("-1\n");return 0; 58 } 59 // inc(i,1,n)printf("%d ",d[i]);putchar('\n'); 60 inc(i,1,n)s+=d[i]; 61 printf("%lld\n",s); 62 return 0; 63 }