一开始用的STL一直超时不能过,后来发现AC的代码基本都用的普通邻接表,然后改了一下13s,T=T,效率太低了。然后把某大神,详情戳链接http://acm.hust.edu.cn/vjudge/problem/viewSource.action?id=1199083的300+ms的代码加上自己的优化成功到了85ms,限时30s的程序还是挺有成就感的。
题目分析:
一个黑格子要和相邻的两个白格子构成一块,也就是成直角形状,因此,每个黑块必须和相邻上下白块中的一个匹配,同样左右白块必须也有一个和它匹配,将黑块拆成两个点, 这样问题就变成二分图的匹配问题了。
我的TLE的代码:
#include <iostream> #include <sstream> #include <cstdio> #include <climits> #include <cstring> #include <cstdlib> #include <string> #include <stack> #include <map> #include <cmath> #include <vector> #include <queue> #include <algorithm> #define esp 1e-6 #define pi acos(-1.0) #define pb push_back #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define mp(a, b) make_pair((a), (b)) #define in freopen("in.txt", "r", stdin); #define out freopen("out.txt", "w", stdout); #define print(a) printf("%d\n",(a)); #define bug puts("********))))))"); #define stop system("pause"); #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++) #define inf 0x0f0f0f0f using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int, int> pii; typedef vector<pii,int> VII; typedef vector<int>:: iterator IT; const int maxn = 555; char maze[maxn][maxn]; int R, C; int flag[maxn * maxn]; int match[maxn * maxn]; VI g[maxn * maxn]; vector<pii> BLK; bool dfs(int x) { for(int i = 0; i < g[x].size(); i++) { int v = g[x][i]; if(!flag[v]) { flag[v] = 1; if(match[v] == -1 || dfs(match[v])) { match[v] = x; return true; } } } return false; } int main(void) { int T, t; scanf("%d", &T); memset(maze, -1, sizeof(maze)); for(t = 1; t <= T; t++) { int b = 0, w = 0; BLK.clear(); for(int i = 0; i < maxn*maxn; i++) g[i].clear(); scanf("%d%d", &R, &C); while(getchar() != '\n') ; for(int i = 1; i <= R; i++) { scanf("%s", maze[i] + 1); for(int j = 1; j <= C; j++) if(maze[i][j] == 'B') b++, BLK.pb(mp(i, j)); else if(maze[i][j] == 'W') w++; } if(b*2 != w) puts("NO"); else { for(int i = 0; i < BLK.size(); i++) { int x = BLK[i].first; int y = BLK[i].second; if(maze[x-1][y] == 'W') g[i].pb((x-1)*C+y); if(maze[x+1][y] == 'W') g[i].pb((x+1)*C+y); if(maze[x][y-1] == 'W') g[i+b].pb(x*C+y-1); if(maze[x][y+1] == 'W') g[i+b].pb(x*C+y+1); } memset(match, -1, sizeof(match)); int i; for( i = 0; i < b; i++) { memset(flag, 0, sizeof(flag)); if(!dfs(i) || !dfs(i+b)) break; } if(i < b) puts("NO"); else puts("YES"); } } return 0; }
改后的代码:
#include <iostream> #include <sstream> #include <cstdio> #include <climits> #include <cstring> #include <cstdlib> #include <string> #include <stack> #include <map> #include <cmath> #include <vector> #include <queue> #include <algorithm> #define esp 1e-6 #define pi acos(-1.0) #define pb push_back #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define mp(a, b) make_pair((a), (b)) #define in freopen("in.txt", "r", stdin); #define out freopen("out.txt", "w", stdout); #define print(a) printf("%d\n",(a)); #define bug puts("********))))))"); #define stop system("pause"); #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++) #define inf 0x0f0f0f0f using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int, int> pii; typedef vector<pii> VII; typedef vector<pii, int> VIII; typedef VI:: iterator IT; int n,m; char s[600][600]; int B[600][600]; int W[600][600]; int link[300000]; int vis[300000]; int b,w; VII BLK; struct bian { int v,next; }e[1000000]; int head[300000]; int num; int now; void add(int u,int v) { e[num].v=v; e[num].next=head[u]; head[u]=num++; } bool dfs(int k) { for(int h=head[k];h!=-1;h=e[h].next) { int v=e[h].v; if(vis[v]==now) continue; vis[v]=now; if(link[v]==-1||dfs(link[v])) { link[v]=k; return 1; } } return 0; } int main() { int T; scanf("%d",&T); while (T--) { BLK.clear(); num=0; memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); memset(s,0,sizeof(s)); for(int i=0;i<n;i++) scanf("%s",s[i]); b=w=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) { if(s[i][j]=='B') B[i][j]=++b, BLK.pb(mp(i, j)); if(s[i][j]=='W') W[i][j]=++w; } if(b*2!=w) { puts("NO"); continue; } else { for(int k = 0; k < BLK.size(); k++) { int i = BLK[k].first; int j = BLK[k].second; if(s[i][j]=='B') { if(s[i-1][j]=='W') add(B[i][j],W[i-1][j]); if(s[i+1][j]=='W') add(B[i][j],W[i+1][j]); if(s[i][j-1]=='W') add(B[i][j]+b,W[i][j-1]); if(s[i][j+1]=='W') add(B[i][j]+b,W[i][j+1]); } } memset(link,-1,sizeof(link)) ; memset(vis,0,sizeof(vis)); int i; for(i=1;i<=b*2;i++) { now=i; if(!dfs(i)) break; } if(i > b*2) puts("YES"); else puts("NO"); } } return 0; }