呃……hungry的原理应该是感性理解一下就能懂……
反正就是一路往前增广嘛……感性理解一下,贪心肯定就是最优了
今天考试的T1,签到题想撞壁打算yy一下hungry,不幸RE,忘了在dfs的时候打个vis
题目大意:二分图,求保留最少边数使每个点度数至少为一
不管了,假装是个hungry的版吧23333
应该没有什么bug,反正这个算法模拟一下就好……听说跑得挺快然而……人丑自带大常数2333
#include<bits/stdc++.h>
#define MAXN 2005
#define MAXM 1000005
using namespace std; int n,m,k;
struct t1{
int to,nxt;
}edge[MAXM<<1]; int cnt_edge=0;
int fst[MAXN];
void addedge(int x,int y){
edge[++cnt_edge].to=y;
edge[cnt_edge].nxt=fst[x];
fst[x]=cnt_edge;
}
int tag[MAXN],cnt=0;
int vis[MAXN];
int dfs(int now,int stp){
// printf("%d\n",now);
if(vis[now]) return 0;
vis[now]=1;
for(int tmp=fst[now];tmp;tmp=edge[tmp].nxt){
if(edge[tmp].to==tag[now]||vis[edge[tmp].to]) continue;
if(!tag[edge[tmp].to])
return tag[now]=edge[tmp].to,tag[edge[tmp].to]=now,1;
else{
if(dfs(tag[edge[tmp].to],stp+1))
return tag[edge[tmp].to]=now,tag[now]=edge[tmp].to,1;
}
}
return 0;
}
int read_x,read_y;
int main(){
freopen("CONF.in","r",stdin);
freopen("CONF.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;++i){
scanf("%d%d",&read_x,&read_y);
addedge(read_x,read_y+n);
addedge(read_y+n,read_x);
}
int nn=n+m;
for(int i=1;i<=nn;++i){
memset(vis,0,sizeof vis);
if(!tag[i])
if(dfs(i,1)) ++cnt;
}
for(int i=1;i<=nn;++i) if(!tag[i]) ++cnt;
printf("%d",cnt);
return 0;
}