zoukankan      html  css  js  c++  java
  • Fire Net HDU

    把每一列中相邻的 .  缩为一个点 作为二分图的左边

    把每一行中相邻的  .  缩为一个点 作为二分图的右边

    然后求最大匹配即可

    这题用匈牙利足够了,我用的hk

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <cmath>
    #include <algorithm>
    #define mem(a, b) memset(a, b, sizeof(a))
    using namespace std;
    const int maxn = 10010, INF = 0x7fffffff;
    int dx[maxn], dy[maxn], cx[maxn], cy[maxn], used[maxn];
    int row[5][5], col[5][5];
    int nx, ny, dis;
    vector<int> G[40005];
    char str[5][5];
    int n;
    int bfs()
    {
        queue<int> Q;
        dis = INF;
        mem(dx, -1);
        mem(dy, -1);
        for(int i=1; i<=nx; i++)
        {
            if(cx[i] == -1)
            {
                Q.push(i);
                dx[i] = 0;
            }
        }
        while(!Q.empty())
        {
            int u = Q.front(); Q.pop();
            if(dx[u] > dis) break;
            for(int v=0; v<G[u].size(); v++)
            {
                int i = G[u][v];
                if(dy[i] == -1)
                {
                    dy[i] = dx[u] + 1;
                    if(cy[i] == -1) dis = dy[i];
                    else
                    {
                        dx[cy[i]] = dy[i] + 1;
                        Q.push(cy[i]);
                    }
                }
            }
        }
        return dis != INF;
    }
    
    int dfs(int u)
    {
        for(int v=0; v<G[u].size(); v++)
        {
            int i = G[u][v];
            if(!used[i] && dy[i] == dx[u] + 1)
            {
                used[i] = 1;
                if(cy[i] != -1 && dis == dy[i]) continue;
                if(cy[i] == -1 || dfs(cy[i]))
                {
                    cy[i] = u;
                    cx[u] = i;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int hk()
    {
        int res = 0;
        mem(cx, -1);
        mem(cy, -1);
        while(bfs())
        {
            mem(used, 0);
            for(int i=1; i<=nx; i++)
            {
                if(cx[i] == -1 && dfs(i)) res++;
            }
        }
        return res;
    }
    
    
    int main()
    {
        while(cin>> n && n)
        {
    
            for(int i=0; i<100; i++) G[i].clear();
            mem(row, -1);
            mem(col, -1);
            nx = ny = 1;
            for(int i=0; i<n; i++)
            {
                cin>> str[i];
            }
            for(int i=0; i<n; i++)
            {
                for(int j=0; j<n; j++)
                {
                    if(str[i][j] == '.' && row[i][j] == -1)
                    {
                        for(int k=j; str[i][k]=='.' && k<n; k++)
                            row[i][k] = nx;
                        nx++;
                    }
                    if(str[j][i] == '.' && col[j][i] == -1)
                    {
                        for(int k=j; str[k][i]=='.' && k<n; k++)
                            col[k][i] = ny;
                        ny++;
                    }
                }
            }
            nx -= 1, ny -= 1;
            for(int i=0; i<n; i++)
                for(int j=0; j<n; j++)
                    if(str[i][j] == '.')
                        G[row[i][j]].push_back(nx + col[i][j]), G[nx + col[i][j]].push_back(row[i][j]);
    
    
    
            cout<< hk() <<endl;
    
    
    
        }
    
    
        return 0;
    }
    View Code

    搜索写法:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    const int maxn = 6, INF = 0xfffffff;
    typedef long long LL;
    char str[maxn][maxn];
    int vis[maxn][maxn];
    int n, minn;
    int check(int x,int y)
    {
        for(int i=x-1; i>=0; --i)
        {
            if(vis[i][y])
                return 0;
            if(str[i][y] == 'X')
                break;
        }
        for(int i=y-1; i>=0; --i)
        {
            if(vis[x][i])
                return 0;
            if(str[x][i] == 'X')
                break;
        }
        return 1;
    }
    
    
    
    void dfs(int inx, int k)
    {
        if(inx == n*n)
        {
            minn = max(k, minn);
            return;
        }
    
        int x = inx / n;
        int y = inx % n;
        if(str[x][y] == '.' && check(x,y))
        {
            vis[x][y] = 1;
            dfs(inx+1, k+1);
            vis[x][y] = 0;
        }
        dfs(inx+1, k);
    }
    
    
    int main()
    {
        while(cin>>n && n)
        {
            minn = -INF;
            mem(vis,0);
            mem(str,0);
            for(int i=0;i<n;i++)
                cin>>str[i];
            dfs(0,0);
            cout<<minn<<endl;
    
        }
    
    
    
    
    
        return 0;
    }
    View Code
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    hash联接算法
    Nginx实现WEB故障转移以及重定向
    MSSQL分区表
    SSO示例
    MSMQ 跨服务器读写队列
    利用Heartbeat完成Mysql主-主同步
    采用heartbeat做Redis的主从切换
    Redis的RDB AOF DATABASE
    Redis初试
    简单线性回归
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9309488.html
Copyright © 2011-2022 走看看