题目:找出唯一的矩阵对应点的方案。
方法:1、想进行一次最大匹配,然后每次删除一条匹配边在进行一次最大匹配,看边是否必须。
吐槽:完全没想到可以这么暴力,还有题目从‘A'开始标号,表明题目数据范围是[1,26]。
/************************************************ Author :DarkTong Created Time :2016/8/1 8:33:20 File Name :Poj_1486.cpp *************************************************/ //#include <bits/stdc++.h> #include <cstring> #include <cstdio> #include <cmath> using namespace std; const int maxn = 30 + 10; int w[maxn][maxn], n, m; int Left[maxn]; bool used[maxn]; bool match(int i) { for(int j=1;j<=m;++j) if(w[i][j]&&!used[j]) { used[j] = true; if(!Left[j]||match(Left[j])) { Left[j] = i; return true; } } return false; } //返回最大匹配数 int hungary() { int res=0; memset(Left, 0, sizeof(Left)); for(int i=1;i<=n;++i) { memset(used, 0, sizeof(used)); if(match(i)) res++; } return res; } int rec[maxn][4], poi[maxn][2], edge[maxn][2], vis[maxn]; int main() { int T, cas=1; while(scanf("%d", &n)==1&&n) { memset(w, 0, sizeof(w)); memset(vis, 0, sizeof(vis)); m=n; for(int i=1;i<=n;++i) scanf("%d%d%d%d", &rec[i][0], &rec[i][1], &rec[i][2], &rec[i][3]); for(int i=1;i<=n;++i) scanf("%d%d", &poi[i][0], &poi[i][1]); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) { if(poi[j][0]>=rec[i][0]&&poi[j][0]<=rec[i][1]&&rec[i][2]<=poi[j][1]&&poi[j][1]<=rec[i][3]) w[j][i]=1;//, printf("--%d %d\n",j,i); } int e, ans=0; if(hungary()==n) { ans=n; for(int i=1;i<=n;++i) edge[i][0]=Left[i], edge[i][1]=i; for(int i=1;i<=n;++i) { w[edge[i][0]][edge[i][1]]=0; if(hungary()==n) { // printf("%d %d\n", edge[i][0], edge[i][1]); vis[i]=1; ans--; } w[edge[i][0]][edge[i][1]]=1; } } printf("Heap %d\n", cas++); if(ans==0) puts("none\n"); else { for(int i=1;i<=n;++i) if(!vis[i]) { printf("(%c,%d) ", 'A'+edge[i][1]-1, edge[i][0]); } puts("\n"); } } return 0; }
转载于:https://www.cnblogs.com/DarkTong/p/5724673.html