题目传送门
分析:
首先就是二分
然后。。。
混合图欧拉回路是sm。。。
看了题解Orz
首先要回到原来的点的话,那么每个点入度和出度要相等。。。
这。。和网络流进入点之后就出去不是一样的吗。。
又由于有的边可以反向
反向后又会改变两个点+-2的流量
于是考虑上下界网络流
每条单向边容量设为1
每条双向边随便定向,连(-1,1)的边
wsm会出现负数?因为-1可以代表反向流
但是貌似并不影响上下界网络流诶。。。
哦摩西罗伊2333
直接跑就好了

#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #define maxn 3005 #define maxm 500005 #define INF 0x3f3f3f3f using namespace std; inline int getint() { int num=0,flag=1;char c; while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1; while(c>='0'&&c<='9')num=num*10+c-48,c=getchar(); return num*flag; } int n,m,S,T; int fir[maxn],nxt[maxm],to[maxm],cap[maxm],cnt; int h[maxn],tp[maxn]; struct node{ int a,b,c,d; }E[maxm]; int f[maxn]; inline void newnode(int u,int v,int w) {to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt,cap[cnt]=w;} inline void insert(int u,int v,int w) {newnode(u,v,w),newnode(v,u,0);} inline bool bfs() { memset(h,-1,sizeof h); queue<int>Q;h[S]=0,Q.push(S); while(!Q.empty()) { int u=Q.front();Q.pop(); for(int i=fir[u];i;i=nxt[i]) if(cap[i]&&!~h[to[i]])h[to[i]]=h[u]+1,Q.push(to[i]); } return ~h[T]; } inline int dfs(int u,int flow) { if(u==T)return flow; int used=0; for(int i=tp[u];i;i=nxt[i]) { tp[u]=i; if(cap[i]&&h[to[i]]==h[u]+1) { int w=flow-used; w=dfs(to[i],min(cap[i],w)); cap[i]-=w,cap[i^1]+=w,used+=w; if(used==flow)return flow; } } if(!used)h[u]=-1; return used; } inline int dinic() { int num=0; while(bfs())memcpy(tp,fir,sizeof fir),num+=dfs(S,INF); return num; } inline bool check(int num) { memset(fir,0,sizeof fir);cnt=1; memset(f,0,sizeof f); for(int i=1;i<=m;i++) { if(E[i].c<=num&&E[i].d<=num)f[E[i].a]--,f[E[i].b]++,insert(E[i].b,E[i].a,2); else if(E[i].c<=num)f[E[i].a]--,f[E[i].b]++; else if(E[i].d<=num)f[E[i].b]--,f[E[i].a]++; else return 0; } int sum=0; for(int i=1;i<=n;i++) { if(f[i]&1)return 0; if(f[i]>0)insert(S,i,f[i]),sum+=f[i]; else insert(i,T,-f[i]); } return sum==dinic(); } int main() { n=getint(),m=getint();S=n+1,T=S+1; for(int i=1;i<=m;i++)E[i].a=getint(),E[i].b=getint(),E[i].c=getint(),E[i].d=getint(); int l=0,r=INF; while(l<r) { int mid=(l+r)>>1; if(check(mid))r=mid; else l=mid+1; } if(l==INF)printf("NIE "); else printf("%d ",l); }