hdu 1281 棋盘游戏
http://acm.hdu.edu.cn/showproblem.php?pid=1281
题意:一个N*M的棋盘,在格子里放尽量多的一些国际象棋里面的“车”,并且使得他们不能互相攻击,在保证尽量多的“车”的前提下,棋盘里有些格子是可以避开的,也就是说,不在这些格子上放车,也可以保证尽量多的“车”被放下。但是某些格子若不放子,就无法保证放尽量多的“车”,这样的格子被称做重要点。算出有多少个这样的重要点。
思路:题目没有说出要严格每个车合占一行和一列。先求出最大可放的车数目ans。然后枚举每个位置不放车的情况下,可放车的最大数目tans,如果tans<ans,则计数cnt++。
实在很难想像这么度复杂度的也能过。试过n=m=100,as[n][m]=1情况下,3s+才出结果~~~

#include<set> #include<map> #include<stack> #include<queue> #include<cmath> #include<bitset> #include<string> #include<climits> #include<cstdio> #include<vector> #include<utility> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define IN puts("in") #define OUT puts("out") #define FR(x) freopen(x,"r",stdin) #define FW(x) freopen(x,"w",stdout) #define MSET(x,y) memset(x,y,sizeof(x)) #define ST system("pause") #define lowbit(x) (x)&(-x) #define L(x) (x)<<1 #define R(x) ((x)<<1)^1 using namespace std; const int maxn = 105; int as[maxn][maxn],vis[maxn],to[maxn]; int n,m; int dfs(int u) { for(int v = 1; v <= m; ++ v) if(as[u][v]&&!vis[v]){ vis[v] = 1; if(to[v]==0||dfs(to[v])){ to[v] = u; return 1; } } return 0; } int maxmatch() { int i,cnt=0; MSET(to,0); for(i = 1; i <= n; ++ i){ MSET(vis,0); cnt+=dfs(i); }return cnt; } int main() { int i,j,k,ans,cnt,cas=0; while(scanf("%d %d %d",&n,&m,&k)==3) { MSET(as,0); for(i = 0; i < k; ++ i){ int x,y; scanf("%d %d",&x,&y); as[x][y] = 1; } ans = maxmatch(); cnt = 0; for(i = 1; i <= n; ++ i) for(j = 1; j<= m; ++ j)if(as[i][j]){ as[i][j] = 0; if(maxmatch()<ans)cnt++; as[i][j] = 1; } printf("Board %d have %d important blanks for %d chessmen.\n",++cas,cnt,ans); } return 0; }