P1525 [NOIP2010 提高组] 关押罪犯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include <iostream>
#include<algorithm>
using namespace std;
int n,m,pre[20005],b[20005];
struct toge
{
int x;
int y;
int z;
};
toge f[100005];
bool cmp(toge xx,toge yy)
{
return xx.z>yy.z;
}
int root(int x)
{
if(pre[x]==x) return x;
return pre[x]=root(pre[x]);
}
int check(int x,int y)
{
x=root(x);
y=root(y);
return x==y;
}
void ad(int x,int y)
{
x=root(x);
y=root(y);
pre[y]=x;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
pre[i]=i;
}
for(int i=1;i<=m;i++)
{
cin>>f[i].x>>f[i].y>>f[i].z;
}
sort(f+1,f+1+m,cmp);
for(int i=1;i<=m+1;i++)
{
if(check(f[i].x,f[i].y))
{
cout<<f[i].z;
return 0;
}
else
{
if(!b[f[i].x]) b[f[i].x]=f[i].y;
else
{
ad(b[f[i].x],f[i].y);
}
if(!b[f[i].y]) b[f[i].y]=f[i].x;
else
{
ad(b[f[i].y],f[i].x);
}
}
}
}
利用并查集来做,不需要关注那个监狱,只需要关注是否存在两个犯人在同一个监狱。
P3386 【模板】二分图最大匹配 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<iostream>
#include<cstring>
using namespace std;
int n,m,e,mapa[505][505],u,v,used[505],linker[505];
bool dfs(int x)
{
for(int i=1;i<=m;i++)
{
if(mapa[x][i]&&!used[i])
{
used[i]=1;
if(linker[i]==0||dfs(linker[i]))
{
linker[i]=x;
return true;
}
}
}
return false;
}
int hungary()
{
int ans=0;
for(int i=1;i<=n;i++)
{
memset(used,0,sizeof(used));
if(dfs(i)) ans++;
}
return ans;
}
int main()
{
cin>>n>>m>>e;
for(int i=1;i<=e;i++)
{
cin>>u>>v;
mapa[u][v]=1;
}
cout<<hungary();
}
二分图最大匹配问题的匈牙利算法
P1129 [ZJOI2007] 矩阵游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<iostream>
#include<cstring>
using namespace std;
int t,n,mapa[202][202];
int used[202],judge;
int linker[202];
bool dfs(int x)
{
for(int i=1;i<=n;i++)
{
if(mapa[x][i]&&!used[i])
{
used[i]=1;
if(!linker[i]||dfs(linker[i]))
{
linker[i]=x;
return true;
}
}
}
return false;
}
int main()
{
cin>>t;
while(t--)
{
memset(linker,0,sizeof(linker));
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>mapa[i][j];
}
}
int a=0;
for(int i=1;i<=n;i++)
{
if(mapa[i][i]==0)
{
a=1;
}
}
if(a==0)
{
cout<<"Yes"<<endl;
continue;
}
judge=0;
for(int i=1;i<=n;i++)
{
memset(used,0,sizeof(used));
if(!dfs(i))
{
cout<<"No"<<endl;
judge=1;
break;
}
}
if(judge==0) cout<<"Yes"<<endl;
}
}
只要保证存在n个黑格子满足任意两个格子的行和列分别不同即可,如果采用dfs(step)的方式会超时,将表格转化为二分图用匈牙利算法有更好的效率;