P1525 [NOIP2010 提高组] 关押罪犯
并查集
#include<bits/stdc++.h>
#define f(i,a,b) for(int (i)=(a);(i)<=(b);++i)
using namespace std;
const int N=20005;
int n,m,L;
int ob[N],root[N];
struct linker{
int x,y,v;
};
inline int read()
{
int t=1,ans=0;
char x=getchar();
while(x<'0'||x>'9'){
if(x=='-') t=-1;
x=getchar();
}
while(x>='0'&&x<='9'){
ans=ans*10+x-'0';
x=getchar();
}
return ans*t;
}
bool cmp(const linker x,const linker y)
{
return x.v>y.v;
}
int fa(const int x)
{
if(x!=root[x])
root[x]=fa(root[x]);
return root[x];
}
inline void add(const int x,const int y)
{
int f1=fa(x),f2=fa(y);
if(f1!=f2)
root[f2]=f1;
return;
}
int main()
{
linker a[100005];
n=read(),L=read();
f(i,1,n)
root[i]=i;
f(i,1,L){
a[i].x=read(),a[i].y=read(),a[i].v=read();
}
sort(a+1,a+1+L,cmp);
f(i,1,L){
if(fa(a[i].x)==fa(a[i].y)){
cout<<a[i].v;
return 0;
}
if(!ob[a[i].x]) ob[a[i].x]=a[i].y;
else add(ob[a[i].x],a[i].y);
if(!ob[a[i].y]) ob[a[i].y]=a[i].x;
else add(ob[a[i].y],a[i].x);
}
cout<<0;
return 0;
}
P3386 【模板】二分图最大匹配
匈牙利算法
#include<bits/stdc++.h>
#define ll long long
#define lowbit(x) (x)&(-x)
#define f(i,a,b) for(int (i)=(a);(i)<=(b);++i)
#define Ma(x,y) make_pair((x),(y))
#define mem0(x) memset((x),0,sizeof(x))
using namespace std;
const int N=2001;
int n,m,L;
int ink[N][N];
int used[N],vis[N];
int ans=0;
bool dfs(const int x)
{
f(i,1,m){
if(vis[i] || !ink[x][i]) continue;
vis[i]=1;
if(used[i]==0 || dfs(used[i])){
used[i]=x;
return 1;
}
}
return 0;
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>m>>L;
f(i,1,L){
int a,b;
cin>>a>>b;
if(a>n||b>m||a<1||b<1) continue;
ink[a][b]=1;
}
f(i,1,n){
mem0(vis);
if(dfs(i)) ++ans;
}
cout<<ans;
return 0;
}
P1129 [ZJOI2007] 矩阵游戏
必须每行每列都有才可能完成,易得即使每行每列都有也不一定可以完成。每一行都必须去对应,也就是说每一行通过行变化要对应某一列(变成了新的矩阵,不用担心变化对原来矩阵的影响),匈牙利算法。
#include<bits/stdc++.h>
#define ll long long
#define lowbit(x) (x)&(-x)
#define f(i,a,b) for(int (i)=(a);(i)<=(b);++i)
#define Ma(x,y) make_pair((x),(y))
#define mem0(x) memset((x),0,sizeof(x))
using namespace std;
const int N=401;
int n;
int ans=0;
int b[N],c[N];
int cnt=0,nex[N*N],to[N*N],fr[N];
int used[N],lin[N];
inline void clear()
{
f(i,1,cnt)
nex[i]=to[i]=0;
f(i,1,n)
fr[i]=0;
return;
}
inline void add(int x,int y)
{
++cnt;
nex[cnt]=fr[x];
fr[x]=cnt;
to[cnt]=y;
}
inline bool dfs(const int x)
{
for(int i=fr[x];i;i=nex[i]){
if(used[to[i]]) continue;
used[to[i]]=1;
if(lin[to[i]]==0 || dfs(lin[to[i]])){
lin[to[i]]=x;
return 1;
}
}
return 0;
}
inline bool check()
{
mem0(lin);
f(i,1,n){
mem0(used);
if(!dfs(i)) return 0;
}
return 1;
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int T;
cin>>T;
while(T--)
{
clear();
cin>>n;
f(i,1,n)
f(j,1,n){
int a;
cin>>a;
if(a==1){
add(i,j);
}
}
if(check()) cout<<"Yes\n";
else cout<<"No\n";
}
return 0;
}