大家好,又见面了,我是全栈君。
小希和Gardon在玩一个游戏:对一个N*M的棋盘,在格子里放尽量多的一些国际象棋里面的“车”,并且使得他们不能互相攻击,这当然很简单,但是Gardon限制了只有某些格子才可以放,小希还是很轻松的解决了这个问题(见下图)注意不能放车的地方不影响车的互相攻击。
所以现在Gardon想让小希来解决一个更难的问题,在保证尽量多的“车”的前提下,棋盘里有些格子是可以避开的,也就是说,不在这些格子上放车,也可以保证尽量多的“车”被放下。但是某些格子若不放子,就无法保证放尽量多的“车”,这样的格子被称做重要点。Gardon想让小希算出有多少个这样的重要点,你能解决这个问题么?
先DFS求出点数,再用二分匹配求解
1 #include<stdio.h>
2 #include<string.h>
3
4 const int maxn=1e5+5; 5 const int maxm=1e5+5; 6
7 int head[maxn],point[maxm],nxt[maxm],size; 8 int match[maxn],vis[maxn]; 9 int get[maxn]; 10
11 void init(){ 12 memset(head,-1,sizeof(head)); 13 size=0; 14 memset(match,-1,sizeof(match)); 15 memset(get,-1,sizeof(get)); 16 } 17
18 void add(int a,int b){ 19 point[size]=b; 20 nxt[size]=head[a]; 21 head[a]=size++; 22 } 23
24 int del; 25
26 int dfs(int s,bool F){ 27 for(int i=head[s];~i;i=nxt[i]){ 28 if(!F&&i==del)continue; 29 int j=point[i]; 30 if(!vis[j]){ 31 vis[j]=1; 32 if(match[j]==-1||dfs(match[j],F)){ 33 if(F){ 34 match[j]=s; 35 get[s]=i; 36 } 37 return 1; 38 } 39 } 40 } 41 return 0; 42 } 43
44
45 int main(){ 46 int T=0; 47 int n,m,k; 48 while(scanf("%d%d%d",&n,&m,&k)!=EOF){ 49 ++T; 50 init(); 51 while(k--){ 52 int a,b; 53 scanf("%d%d",&a,&b); 54 add(a,n+b); 55 } 56 int ans1=0; 57 for(int i=1;i<=n;++i){ 58 memset(vis,0,sizeof(vis)); 59 if(dfs(i,1))ans1++; 60 } 61 int ans=0; 62 for(int i=1;i<=n;++i){ 63 if(get[i]!=-1){ 64 del=get[i]; 65 match[point[del]]=-1; 66 get[i]=-1; 67 memset(vis,0,sizeof(vis)); 68 if(!dfs(i,0))ans++; 69 get[i]=del; 70 match[point[del]]=i; 71 } 72 } 73 printf("Board %d have %d important blanks for %d chessmen.\n",T,ans,ans1); 74 } 75 return 0; 76 }
View Code
转载于:https://www.cnblogs.com/cenariusxz/p/6578414.html
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/108612.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...