Brief description of the title
Give you an undirected graph with \ (n \) points \ (m \) edges to determine whether some edges can be dyed white, others dyed black, and there is no solid color ring.
\ (n \ le 501, m \ le 2n \)
Ideas
A picture has \ (E \) edges and \ (V \) points. Then, it must satisfy the ring without solid color, the maximum value of \ (E \) is \ (2 (V-1) \) (in this case, white and black form two spanning trees respectively).
\ (E \ le 2V-2 \) , can become \ (E-2V \ le -2 \) .
Then all of our current graphs must satisfy the conditions, and of course any of the subgraphs also satisfy the conditions. We can convert: \ (E-2V \) the largest subgraph and also meet \ (E-2V \ Le -2 \) .
How to find the largest subgraph of \ (E-2V \) ? Think of edges as points and points as edges. This becomes the maximum weight closed subgraph problem.
(No Baidu)
Code
#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
#define N 100055
#define INF 0x5f5f5f5f
#define F(i,l,r) for(int i=l;i<=r;++i)
#define D(i,r,l) for(int i=r;i>=l;--i)
#define Fs(i,l,r,c) for(int i=l;i<=r;c)
#define Ds(i,r,l,c) for(int i=r;i>=l;c)
#define MEM(x,a) memset(x,a,sizeof(x))
#define FK(x) MEM(x,0)
#define Tra(i,u) for(int i=G.Start(u),v=G.To(i);~i;i=G.Next(i),v=G.To(i))
#define p_b push_back
#define sz(a) ((int)a.size())
#define iter(a,p) (a.begin()+p)
int I()
{
int x=0;char c=getchar();int f=1;
while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return (x=(f==1)?x:-x);
}
void Rd(int cnt,...)
{
va_list args; va_start(args,cnt);
F(i,1,cnt) {int* x=va_arg(args,int*);(*x)=I();}
va_end(args);
}
class Graph
{
public:
int EdgeCount;
int head[N];
int To[N],Label[N],Next[N];
inline void clear()
{
MEM(head,-1);
EdgeCount=-1;
}
inline void AddEdge(int u,int v,int w)
{
++EdgeCount;
To[EdgeCount]=v; Label[EdgeCount]=w; Next[EdgeCount]=head[u];
head[u]=EdgeCount;
}
int Source,Sink;
int deep[N];
queue<int> Q;
bool BFS()
{
while(!Q.empty()) Q.pop();
FK(deep);
Q.push(Source);
deep[Source]=1;
do
{
int u=Q.front();Q.pop();
for(register int i=head[u];~i;i=Next[i])
{
int v=To[i];
if (!deep[v] and Label[i])
{
deep[v]=deep[u]+1;
if (v==Sink) {return true;}
Q.push(v);
}
}
}while(!Q.empty());
return (bool)(deep[Sink]);
}
int DFS(int u,int MinFlow)
{
if (u==Sink) return MinFlow;
int rest=MinFlow;
for(register int i=head[u];~i and rest;i=Next[i])
{
int v=To[i];
if (deep[v]==deep[u]+1 and Label[i]!=0)
{
int d=DFS(v,min(MinFlow,Label[i]));
if (!d) deep[v]=0;
Label[i]-=d;
Label[i^1]+=d;
rest-=d;
}
}
return MinFlow-rest;
}
int Dinic()
{
int ans=0;
while(BFS()) ans+=DFS(Source,INF);
return ans;
}
}Nt; // 网络流
int n,m;
int uu[N],vv[N];
void Input()
{
Rd(2,&n,&m);
F(i,1,m) uu[i]=I(),vv[i]=I();
}
#define S Nt.Source
#define T Nt.Sink
#define AddFlow(u,v,w) {Nt.AddEdge(u,v,w); Nt.AddEdge(v,u,0);}
// 建流
int MustChoose(int s) // 强制选择点 s 的答案
{
Nt.clear();
F(i,1,m)
{
int u=uu[i],v=vv[i];
AddFlow(S,i,1);
AddFlow(i,m+u,INF);
AddFlow(i,m+v,INF);
}
F(i,1,n) if (i!=s)
{
AddFlow(i+m,T,2);
}
return m-2-Nt.Dinic();
}
void Soviet()
{
S=n+m+1,T=n+m+2;
int ans=-INF;
F(i,1,n)
{
ans=max(ans,MustChoose(i)); // 把每个强制选 i 的答案取 max,就是最大闭合子图了
if (ans>-2) {puts("No"); return;} // 每一个都要 <=-2,有一个 > 就直接输出 No
}
puts((ans<=-2)?"Yes":"No");
}
#define Flan void
Flan IsMyWife()
{
int t=I();
F(i,1,t)
{
Input();
Soviet();
}
}
}
int main()
{
Flandre_Scarlet::IsMyWife();
getchar();getchar();
return 0;
}