UVALive 5903 Piece it together

一开始用的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;
}

posted on 2013-10-08 17:00  rootial  阅读(327)  评论(0编辑  收藏  举报

导航