您的位置:首页 > 其它

【图论】【二分图匹配】[ZOJ 1002]Fire Net

2015-07-27 17:02 483 查看
这道题目就是对不同的方向的同一行或者列的连通块进行标号,然后对方向不同且相交的连通快连边,最后做一次二分图最大匹配就好了。

[code]#include <cstdio>
#include <cstring>
#include <algorithm>
//#include <conio.h>
using namespace std;
const int MAXN = 4;
bool vis[MAXN*MAXN*MAXN];
int Map[MAXN+2][MAXN+2];
int id_v[MAXN+2][MAXN+2];
int id_h[MAXN+2][MAXN+2];
int con[MAXN*MAXN*MAXN];
int idcnt, endcnt;
int n;
const int MAXEN = 16;
const int MAXEM = MAXEN * 2;
struct node{
    int v;
    node *next;
}Edges[MAXEM*2+10], *adj[MAXEN+10], *ecnt=Edges;
void addedge(int u, int v){
    ++ecnt;
    ecnt->v = v;
    ecnt->next = adj[u];
    adj[u] = ecnt;
}
bool dfs(int u){
    //getch();
    for(node *p=adj[u];p;p=p->next){
        if(!vis[p->v]){
            vis[p->v] = true;
            if(!con[p->v] || dfs(con[p->v])){
                con[u] = p->v;
                con[p->v] = u;
                return true;
            }
        }
    }
    return false;
}
int work(){
    int ret = 0;
    for(int i=1;i<=endcnt;i++) if(!con[i]){
        memset(vis, 0, sizeof vis);
        ret += dfs(i);
    }
    return ret;
}
bool read(){
    char t[20];
    scanf("%d", &n);
    if(!n) return false;
    for(int i=1;i<=n;i++){
        scanf("%s", t);
        for(int j=0;j<n;j++)
            Map[i][j+1] = t[j] == 'X' ? 0 : 1;
    }
    return true;
}
void prepare(){
    idcnt=0;
    memset(adj, 0, sizeof adj);
    ecnt=Edges;
    memset(con, 0, sizeof con);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++) if(Map[i][j]){
            if(!Map[i][j-1]) idcnt++;
            id_h[i][j] = idcnt;
        }
    }
    endcnt = idcnt;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++) if(Map[j][i]) {
            if(!Map[j-1][i]) idcnt++;
            id_v[j][i] = idcnt;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++) if(Map[i][j]){
            addedge(id_h[i][j], id_v[i][j]);
            addedge(id_v[i][j], id_h[i][j]);
        }
    }
}
int main(){
    while(read()){
        prepare();
        printf("%d\n", work());
    }

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: