zoukankan      html  css  js  c++  java
  • HDU 3605 Escape

    状态压缩+最大流

    因为最多只有10个星球,所以人最多只有1<<10种。所以按照人的种类来建图。

    此题有毒,光是输入就TLE了,联系了HDU OJ管理员胡杰,把时间放宽为2000ms,最终,用了输入挂,用了C++提交,1200ms过了;不用输入挂 用C++ 1700ms。

    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 1500 + 10;
    const int INF = 0x7FFFFFFF;
    
    struct Edge
    {
        int from, to, cap, flow;
    };
    vector<Edge>edges;
    vector<int>G[maxn];
    bool vis[maxn];
    int d[maxn];
    int cur[maxn];
    int n, m, s, t;
    
    
    int Scan()
    {
        int res = 0, ch, flag = 0;
    
        if ((ch = getchar()) == '-')             //判断正负
            flag = 1;
    
        else if (ch >= '0' && ch <= '9')           //得到完整的数
            res = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9')
            res = res * 10 + ch - '0';
    
        return flag ? -res : res;
    }
    
    
    //求出层次网络
    bool BFS()
    {
        memset(vis, 0, sizeof(vis));
        queue<int>Q;
        Q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while (!Q.empty())
        {
            int x = Q.front();
            Q.pop();
            for (int i = 0; i<G[x].size(); i++)
            {
                Edge& e = edges[G[x][i]];
                if (!vis[e.to] && e.cap>e.flow)
                {
                    vis[e.to] = 1;
                    d[e.to] = d[x] + 1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }
    
    
    //加边
    void AddEdge(int from, int to, int cap)
    {
        Edge r;
        r.from = from;
        r.to = to;
        r.cap = cap;
        r.flow = 0;
        edges.push_back(r);
        Edge d;
        d.from = to;
        d.to = from;
        d.cap = 0;
        d.flow = 0;
        edges.push_back(d);
        m = edges.size();
        G[from].push_back(m - 2);
        G[to].push_back(m - 1);
    }
    
    //每个阶段来一次DFS增广
    int DFS(int x, int a)
    {
        if (x == t || a == 0) return a;
        int flow = 0, f;
        for (int i = cur[x]; i<G[x].size(); i++)
        {
            Edge& e = edges[G[x][i]];
            if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow)))>0)
            {
                e.flow += f;
                edges[G[x][i] ^ 1].flow -= f;
                flow += f;
                a -= f;
                if (a == 0) break;
            }
        }
        return flow;
    }
    
    //多个阶段,多次建立层次网络。
    int Maxflow(int ss, int tt)
    {
        int flow = 0;
        while (BFS())
        {
            memset(cur, 0, sizeof(cur));
            flow += DFS(ss, INF);
        }
        return flow;
    }
    
    
    int N, M;
    int Tot[maxn];
    int Er[maxn];
    int zh[maxn];
    int ZH[maxn];
    
    int main()
    {
        while (scanf("%d%d", &N, &M) != EOF)
        {
            edges.clear();
            for (int i = 0; i<maxn; i++) G[i].clear();
            memset(Tot, 0, sizeof Tot);
    
            for (int i = 1; i <= N; i++)
            {
                int Ans = 0;
                for (int j = 0; j < M; j++) Er[j] = Scan();
                for (int j = 0; j<M; j++) Ans = Ans + Er[j] * pow(2.0,j);
                Tot[Ans]++;
            }
            s = 1401;
            t = 1400;
            for (int i = 0; i <= (1<<10); i++)
            {
                if (Tot[i])
                {
                    AddEdge(s, i, Tot[i]);
                    int y = i, q = 0, d = 0;
                    while (y) zh[q] = y % 2, y = y / 2, q++;
                    for (int ii = 0; ii<q; ii++)
                    if (zh[ii])
                        AddEdge(i, 1100 + ii, INF);
                }
            }
            for (int i = 0; i<M; i++)
            {
                int x;
                x = Scan();
                AddEdge(1100 + i, t, x);
            }
            int FF = Maxflow(s, t);
            if (FF != N) printf("NO
    ");
            else printf("YES
    ");
        }
        return 0;
    }
  • 相关阅读:
    极简风格的LOGO,收集一波!
    如何利用AI软件中的混合器工具制作文字
    国内有哪些非常有设计感的 App?
    如何用PS制作花型背景图
    怎样去调整摄影作品的背景颜色
    如何用PS把数码拍摄的荷花照片制作成中国风的效果
    PS 抠人像如何抠得干净?
    如何用 Ps 制作毛玻璃穿透效果?
    化装品经过这样PS包装,身价立马翻10倍
    有哪些漂亮的中国风 LOGO 设计?
  • 原文地址:https://www.cnblogs.com/zufezzt/p/4747182.html
Copyright © 2011-2022 走看看