P1525 [NOIP2010 提高组] 关押罪犯
1.思路:这道题只把罪犯放在两个监狱中,首先想到的是二分匹配算法,但后面发现并查集好做,我们只需用优先队列对罪犯间的怨恨值进行排序,怨恨值越高,我们需要优先把罪犯分别安排再两个监狱。并查集方式:敌人的敌人就是朋友。
2.代码:
#include <bits/stdc++.h>
using namespace std;
int fa[20005];
int b[20005];
int ans;
int z1;
int z2;
int n,m;
struct priority
{
int x;
int y;
int c;
bool operator <(const priority &x)const
{
return x.c>c;
}
};
priority_queue<priority>q;
int find(int x)
{
if(fa[x]==x)
{
return x;
}
else
{
fa[x]=find(fa[x]);
return fa[x];
}
}
void merge(int i,int j)
{
fa[find(i)]=find(j);
}
void init()
{
for(int i=1;i<=n;i=i+1)
{
fa[i]=i;
}
}
int main()
{
cin>>n>>m;
init();
for(int i=1;i<=m;i=i+1)
{
int u,o,p;
cin>>u>>o>>p;
q.push((priority){u,o,p});
}
while(!q.empty())
{
priority temp=q.top();
q.pop();
int x1=temp.x;
int y1=temp.y;
if(find(x1)==find(y1))
{
ans=temp.c;
cout<<temp.c<<endl;
break;
}
else
{
if(!b[x1])
{
b[x1]=y1;
}
else
{
merge(b[x1],y1);
}
if(!b[y1])
{
b[y1]=x1;
}
else
{
merge(b[y1],x1);
}
}
}
if(ans==0)
{
cout<<0;
}
}
P3386 【模板】二分图最大匹配
1.思路:没啥好说的,代模板就对了
2.代码:
#include <bits/stdc++.h>
using namespace std;
int n,m,e;
int g[505][505];
int linker[505];
bool used[505];
bool dfs(int u)
{
for(int v=1;v<=m;v=v+1)
{
if(g[u][v]&&!used[v])
{
used[v]=1;
if(linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
return true;
}
}
}
return false;
}
int hungary()
{
int res=0;
memset(linker,-1,sizeof(linker));
for(int u=1;u<=n;u++)
{
memset(used,false,sizeof(used));
if(dfs(u))
{
res++;
}
}
return res;
}
int main()
{
cin>>n>>m;
cin>>e;
for(int i=1;i<=e;i=i+1)
{
int u,v;
cin>>u>>v;
g[u][v]=1;
}
cout<<hungary()<<endl;
}
P1129 [ZJOI2007] 矩阵游戏
1.思路:这个二分图感觉好隐蔽,因为每一个对角线都需要是黑色的,说明每一个列集合中的点都需要与每一个行集合的点匹配,然后换行和换列就是改变点的位置,不影响匹配,所以我们只需进行一次最大匹配搜索就可以了。
2.代码:
#include <bits/stdc++.h>
using namespace std;
int n,m;
int g[205][205];
int linker[205];
bool used[205];
bool dfs(int u)
{
for(int v=1;v<=m;v=v+1)
{
if(g[u][v]&&!used[v])
{
used[v]=1;
if(linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
return true;
}
}
}
return false;
}
int hungary()
{
int res=0;
memset(linker,-1,sizeof(linker));
for(int u=1;u<=n;u++)
{
memset(used,false,sizeof(used));
if(dfs(u))
{
res++;
}
}
return res;
}
int main()
{
int t;
cin>>t;
for(int i=1;i<=t;i=i+1)
{
cin>>n;
m=n;
for(int j=1;j<=n;j=j+1)
{
for(int k=1;k<=n;k=k+1)
{
cin>>g[j][k];
}
}
if(hungary()==n)
{
cout<<"Yes"<<endl;
}
else
{
cout<<"No"<<endl;
}
}
}