坑爹数据= =
一道很弱的查分约束,根据题意连边就好惹,然而添加超级源点会RE= =(一直RE看了下discuss发现段神T了一个钟就是因为这个= =),用priorityqueue优化SPFA会无限超时= =
其实感觉用tarjan判环然后在拓扑图上递推能跑的很快的有空试下
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<cstdlib> #include<bitset> #include<queue> #define LL long long #define ps(x,y) q.push(hhx(x,y)) #define fo(i,a,b) for(int i=a;i<=b;i++) #define down(i,a,b) for(int i=a;i>=b;i--) #define efo(i,x) for(int i=last[x];i!=0;i=e[i].next) using namespace std; LL read() { LL d=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();} return d*f; } #define N 100005 #define S 100001 #define inf 1000000007 struct hhx { int x,dis; hhx(int a,int b):dis(b),x(a){} }; struct edge { int y,c,next; }e[N*2]; int last[N],ne=0; int relax[N],dis[N]; int n,m; void add(int x,int y,int c) { e[++ne].y=y;e[ne].c=c;e[ne].next=last[x];last[x]=ne; } queue<hhx>q; bool spfa() { memset(relax,0,sizeof(relax)); bitset<N+5>inq;inq.reset(); inq[S]=1; fo(i,1,n) { dis[i]=1; ps(i,1); } while(!q.empty()) { hhx now=q.front(); q.pop(); inq[now.x]=0; efo(i,now.x) if(dis[now.x]+e[i].c>dis[e[i].y]) { // cout<<now.x<<' '<<e[i].y<<' '<<dis[now.x]<<' '<<e[i].c<<' '<<dis[e[i].y]<<endl; dis[e[i].y]=dis[now.x]+e[i].c; if(++relax[e[i].y]>=n)return 0; if(inq[e[i].y]==0) { ps(e[i].y,dis[e[i].y]); inq[e[i].y]=1; } } } return 1; } int main() { scanf("%d%d",&n,&m); fo(i,1,m) { int k,x,y;scanf("%d%d%d",&k,&x,&y); if(k==1){add(x,y,0);add(y,x,0);continue;} if(k==2) { if(x==y) { puts("-1"); return 0; } add(x,y,1); continue; } if(k==3){add(y,x,0);continue;} if(k==4) { if(x==y) { puts("-1"); return 0; } add(y,x,1); continue; } if(k==5){add(x,y,0);continue;} } if(!spfa())puts("-1"); else { LL ans=0; fo(i,1,n)ans+=dis[i]; printf("%lld\n",ans); } return 0; }