题意:
给你一个n*m的地图和k个地图上可以放车的点
让你求出最多放多少个车和哪些点是必要的(没有它匹配数就会减少)
思路:
匈牙利求最大匹配,然后一个一个的删除匹配点进行匹配,
如果删除该点后匹配数减少,则这个点就是必要的
代码:
一开始用vector要记删除的点参数比较麻烦
/* *********************************************** //Author :devil //Created Time :2016/5/10 17:22:52 //************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; const int N=105; vector<int>eg[N]; int link[N],used[N],dx; bool vis[N]; bool dfs(int u,int f) { for(int i=0;i<eg[u].size();i++) { int v=eg[u][i]; if(!f&&u==dx&&v==used[dx]) continue; if(!vis[v]) { vis[v]=1; if(link[v]==-1||dfs(link[v],f)) { link[v]=u; if(f) used[u]=v; return 1; } } } return 0; } int main() { //freopen("in.txt","r",stdin); int n,m,k,x,y,cas=0; while(~scanf("%d%d%d",&n,&m,&k)) { memset(link,-1,sizeof(link)); for(int i=1;i<=100;i++) eg[i].clear(); memset(used,0,sizeof(used)); while(k--) { scanf("%d%d",&x,&y); eg[x].push_back(y); } int ma=0,ans=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); ma+=dfs(i,1); } for(int i=1;i<=n;i++) { if(used[i]) { memset(link,-1,sizeof(link)); int now=0; dx=i; for(int j=1;j<=n;j++) { memset(vis,0,sizeof(vis)); now+=dfs(j,0); } if(now!=ma) ans++; } } printf("Board %d have %d important blanks for %d chessmen. ",++cas,ans,ma); } return 0; }
然后索性用邻接矩阵写了。。
/* *********************************************** //Author :devil //Created Time :2016/5/10 17:23:18 //************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; const int N=105; int link[N],used[N],n,m,k; bool mp[N][N],vis[N]; bool dfs(int u,int f) { for(int i=1;i<=m;i++) { if(mp[u][i]&&!vis[i]) { vis[i]=1; if(link[i]==-1||dfs(link[i],f)) { link[i]=u; if(f) used[u]=i; return 1; } } } return 0; } int main() { //freopen("in.txt","r",stdin); int x,y,cas=0; while(~scanf("%d%d%d",&n,&m,&k)) { memset(link,-1,sizeof(link)); memset(mp,0,sizeof(mp)); memset(used,0,sizeof(used)); while(k--) { scanf("%d%d",&x,&y); mp[x][y]=1; } int ma=0,ans=0; for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); ma+=dfs(i,1); } for(int i=1;i<=n;i++) { if(used[i]) { memset(link,-1,sizeof(link)); int now=0; mp[i][used[i]]=0; for(int j=1;j<=n;j++) { memset(vis,0,sizeof(vis)); now+=dfs(j,0); } mp[i][used[i]]=1; if(now!=ma) ans++; } } printf("Board %d have %d important blanks for %d chessmen. ",++cas,ans,ma); } return 0; }