标签:des style blog http io color ar os java
一般图最大匹配带花树+暴力:
先算最大匹配 C1
在枚举每一条边,去掉和这条边两个端点有关的边.....再跑Edmonds得到匹配C2
如果C2+2==C1则这条边再某个最大匹配中

4 4 1 3 2 3 2 4 3 1 6 6 1 2 3 2 3 4 5 2 5 4 5 6
1 2 3 2 4 5
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int maxn=50;
vector<int> ans;
bool G[maxn][maxn],TG[maxn][maxn];
int n,m;
int Match[maxn];
int Start,Finish,NewBase;
int Father[maxn],Base[maxn];
bool InQueue[maxn],InPath[maxn],InBlossom[maxn];
int Count;
queue<int> q;
int FindCommonAncestor(int u,int v)
{
memset(InPath,false,sizeof(InPath));
while(true)
{
u=Base[u];
InPath[u]=true;
if(u==Start) break;
u=Father[Match[u]];
}
while(true)
{
v=Base[v];
if(InPath[v]) break;
v=Father[Match[v]];
}
return v;
}
void ResetTrace(int u)
{
int v;
while(Base[u]!=NewBase)
{
v=Match[u];
InBlossom[Base[u]]=InBlossom[Base[v]]=true;
u=Father[v];
if(Base[u]!=NewBase) Father[u]=v;
}
}
void BlossomContract(int u,int v)
{
NewBase=FindCommonAncestor(u,v);
memset(InBlossom,false,sizeof(InBlossom));
ResetTrace(u); ResetTrace(v);
if(Base[u]!=NewBase) Father[u]=v;
if(Base[v]!=NewBase) Father[v]=u;
for(int tu=1;tu<=n;tu++)
{
if(InBlossom[Base[tu]])
{
Base[tu]=NewBase;
if(!InQueue[tu])
{
q.push(tu);
InQueue[tu]=true;
}
}
}
}
void FindAugmentingPath()
{
memset(InQueue,false,sizeof(InQueue));
memset(Father,0,sizeof(Father));
for(int i=1;i<=n;i++)
Base[i]=i;
while(!q.empty()) q.pop();
q.push(Start); InQueue[Start]=true;
Finish=0;
while(!q.empty())
{
int u=q.front(); q.pop();
InQueue[u]=false;
for(int i=1;i<=n;i++)
{
if(i==u||G[u][i]==false) continue;
int v=i;
if(Base[u]!=Base[v]&&Match[u]!=v)
{
if(v==Start||(Match[v]>0&&Father[Match[v]]>0))
BlossomContract(u,v);
else if(Father[v]==0)
{
Father[v]=u;
if(Match[v]>0)
{
q.push(Match[v]);
InQueue[Match[v]]=true;
}
else
{
Finish=v;
return ;
}
}
}
}
}
}
void AugmentPath()
{
int u,v,w;
u=Finish;
while(u>0)
{
v=Father[u];
w=Match[v];
Match[v]=u;
Match[u]=v;
u=w;
}
}
void Edmonds()
{
memset(Match,0,sizeof(Match));
for(int u=1;u<=n;u++)
{
if(Match[u]==0)
{
Start=u;
FindAugmentingPath();
if(Finish>0) AugmentPath();
}
}
}
int bian[200][2];
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(G,0,sizeof(G));
memset(TG,0,sizeof(TG));
ans.clear();
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
bian[i][0]=u;bian[i][1]=v;
G[u][v]=G[v][u]=1;
TG[u][v]=TG[v][u]=1;
}
Edmonds();
Count=0;
for(int i=1;i<=n;i++)
if(Match[i]) Count++;
for(int i=0;i<m;i++)
{
int u=bian[i][0],v=bian[i][1];
///clear about u,v
for(int j=1;j<=n;j++)
{
G[u][j]=G[j][u]=G[j][v]=G[v][j]=0;
}
Edmonds();
int C2=0;
for(int j=1;j<=n;j++)
if(Match[j]) C2++;
if(C2<Count-2)
ans.push_back(i+1);
///Recover
for(int j=1;j<=n;j++)
{
G[u][j]=TG[u][j]; G[j][u]=TG[j][u];
G[v][j]=TG[v][j]; G[j][v]=TG[j][v];
}
}
int sz = ans.size();
printf("%d\n",sz);
for(int i=0;i<sz;i++)
{
printf("%d",ans[i]);
if(i<sz-1)printf(" ");
}
printf("\n");
}
return 0;
}
HDOJ 4687 Boke and Tsukkomi 一般图最大匹配带花树+暴力
标签:des style blog http io color ar os java
原文地址:http://blog.csdn.net/ck_boss/article/details/40833181