分析:将行和列缩点,即行对应二分图的X部,列对应二分图的Y部,然后交点为连接该行和该列的一条边。匹配时每点都会把整行整列占了,因此就不会出现冲突了。
传送门:hdu1281 棋盘游戏
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <queue> #include <cstdlib> #include <stack> #include <vector> #include <set> #include <map> #define LL long long #define mod 100000000 #define inf 0x3f3f3f3f #define eps 1e-6 #define N 110 #define FILL(a,b) (memset(a,b,sizeof(a))) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define PII pair<int,int> using namespace std; int match[N],vis[N],n,m,k; int g[N][N],a[N*N][2],x,y; int dfs(int u) { for(int i=1;i<=m;i++) { if(!vis[i]&&g[u][i]) { vis[i]=1; if(match[i]==-1||dfs(match[i])) { match[i]=u; return 1; } } } return 0; } int hungary() { memset(match,-1,sizeof(match)); int ans=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(dfs(i))ans++; } return ans; } int main() { int cas=1; while(scanf("%d%d%d",&n,&m,&k)>0) { memset(g,0,sizeof(g)); for(int i=1;i<=k;i++) { scanf("%d%d",&x,&y); g[x][y]=1; a[i][0]=x; a[i][1]=y; } int res=hungary(); int ans=0; for(int i=1;i<=k;i++) { g[a[i][0]][a[i][1]]=0; int maxn=hungary(); if(maxn<res)ans++; g[a[i][0]][a[i][1]]=1; } printf("Board %d have %d important blanks for %d chessmen.\n",cas++,ans,res); } }
传送门:hdu2819 Swap
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <queue> #include <cstdlib> #include <stack> #include <vector> #include <set> #include <map> #define LL long long #define mod 100000000 #define inf 0x3f3f3f3f #define eps 1e-6 #define N 110 #define FILL(a,b) (memset(a,b,sizeof(a))) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define PII pair<int,int> using namespace std; int match[N],vis[N],n,m; int g[N][N],a[N*N][2]; int dfs(int u) { for(int i=1;i<=n;i++) { if(!vis[i]&&g[u][i]) { vis[i]=1; if(match[i]==-1||dfs(match[i])) { match[i]=u; return 1; } } } return 0; } int hungary() { memset(match,-1,sizeof(match)); int ans=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(dfs(i))ans++; } return ans; } int main() { int cas=1; while(scanf("%d",&n)>0) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&g[i][j]); int res=hungary(); if(res!=n) { puts("-1"); continue; } int sum=0,i,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(match[j]==i)break; } if(i==j)continue; sum++; a[sum][0]=i; a[sum][1]=j; swap(match[i],match[j]); } printf("%d\n",sum); for(int i=1;i<=sum;i++) printf("C %d %d\n",a[i][0],a[i][1]); } }
时间: 2024-10-12 09:15:34