zoukankan      html  css  js  c++  java
  • 一系列网络流题目-2016.10.17

    HDU1116:Play on Words

    以前做过的一道题

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<iostream>
    using namespace std;
    int dr[26],dc[26],N,f[26];
    bool e[26],g[26][26];
    bool bfs()
    {
        int i;
        memset(f,0,sizeof(f));
        queue<int> q;
        while (!q.empty()) q.pop();
        for (i=0;i<26;i++)
            if (e[i])
            {
                f[i]=true;
                q.push(i);
                break;
            }
        while (!q.empty())
        {
            int x=q.front();
            q.pop();
            for (i=0;i<26;i++)
                if (g[x][i])
                {
                    if (!f[i])
                    {
                        f[i]=true;
                        q.push(i);
                    }
                }
        }
        for (i=0;i<26;i++)
            if ((e[i]) && (!f[i])) return false;
        return true;
    }
    int main()
    {
        int T,i;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d",&N);
            char s[1024];
            memset(g,0,sizeof(g));
            memset(e,0,sizeof(e));
            memset(dr,0,sizeof(dr));
            memset(dc,0,sizeof(dc));
            for (i=1;i<=N;i++)
            {
                scanf("%s",s);
                int u=s[0]-'a',v=s[strlen(s)-1]-'a';
                g[u][v]=true;
                g[v][u]=true;
                e[u]=true;
                e[v]=true;
                dc[u]++;
                dr[v]++;
            }
            bool flag=bfs();
            int cnt0=0,cnt1=0;
            for (i=0;i<26;i++)
            {
                if (dr[i]-dc[i]>1 || dr[i]-dc[i]<-1) flag=false;
                if (dr[i]-dc[i]==1) cnt0++;
                if (dr[i]-dc[i]==-1) cnt1++;
            }
            if (!((cnt0==0 && cnt1==0)||(cnt0==1 && cnt1==1))) flag=false;
            if (flag) printf("Ordering is possible.
    ");
            else printf("The door cannot be opened.
    ");
        }
        return 0;
    }
    View Code

     

    HDU3549:Flow Problem
    Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 13708 Accepted Submission(s): 6538


    Problem Description
    Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph.

    Input
    The first line of input contains an integer T, denoting the number of test cases.
    For each test case, the first line contains two integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <= 15, 0 <= M <= 1000)
    Next M lines, each line contains three integers X, Y and C, there is an edge from X to Y and the capacity of it is C. (1 <= X, Y <= N, 1 <= C <= 1000)

    Output
    For each test cases, you should output the maximum flow from source 1 to sink N.

    Sample Input
    2
    3 2
    1 2 1
    2 3 1
    3 3
    1 2 1
    2 3 1
    1 3 1

    Sample Output
    Case 1: 1
    Case 2: 2

    Author
    HyperHexagon

    模板题,手写了一下Edmond_Karp.

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <map>
    #include <queue>
    using namespace std;
    int G[100][100], F[100][100];
    int p[100];
    bool f[100];
    int N, M, T;
    queue<int> q;
    int Edmond_Karp() {
        int ret = 0, u, MIN, tmp;
        memset(F, 0, sizeof(F));
        while (1) {
            while (!q.empty()) {
                q.pop();
            }
            MIN = 0x7FFFFFFF;
            memset(f, false, sizeof(f));
            q.push(1);
            f[1] = true;
            while (!q.empty()) {
                u = q.front();
                q.pop();
                for (int i = 1; i <= N; i++) {
                    if (G[u][i] > F[u][i] && !f[i]) {
                        q.push(i);
                        p[i] = u;
                        f[i] = true;
                    }
                }
            }
            if (!f[N]) {
                break;
            }
            for (int i = N; i != 1; i = p[i]) {
                tmp = G[p[i]][i] - F[p[i]][i];
                if (tmp < MIN) {
                    MIN = tmp;
                }
            }
            for (int i = N; i != 1; i = p[i]) {
                F[p[i]][i] += MIN;
                F[i][p[i]] -= MIN;
            }
            ret+=MIN;
        }
        return ret;
    }
    int main() {
        int x, y, c;
        scanf("%d", &T);
        for (int o = 1; o <= T; o++) {
            scanf("%d%d", &N, &M);
            memset(G, 0, sizeof(G));
            for (int i = 0; i < M; i++) {
                scanf("%d%d%d", &x, &y, &c);
                G[x][y] += c;
            }
            printf("Case %d: %d
    ", o, Edmond_Karp());
        }
        return 0;
    }
    View Code

    HDU1532:Drainage Ditches

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 15641 Accepted Submission(s): 7450


    Problem Description
    Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer John has built a set of drainage ditches so that Bessie's clover patch is never covered in water. Instead, the water is drained to a nearby stream. Being an ace engineer, Farmer John has also installed regulators at the beginning of each ditch, so he can control at what rate water flows into that ditch.
    Farmer John knows not only how many gallons of water each ditch can transport per minute but also the exact layout of the ditches, which feed out of the pond and into each other and stream in a potentially complex network.
    Given all this information, determine the maximum rate at which water can be transported out of the pond and into the stream. For any given ditch, water flows in only one direction, but there might be a way that water can flow in a circle.

     

    Input
    The input includes several cases. For each case, the first line contains two space-separated integers, N (0 <= N <= 200) and M (2 <= M <= 200). N is the number of ditches that Farmer John has dug. M is the number of intersections points for those ditches. Intersection 1 is the pond. Intersection point M is the stream. Each of the following N lines contains three integers, Si, Ei, and Ci. Si and Ei (1 <= Si, Ei <= M) designate the intersections between which this ditch flows. Water will flow through this ditch from Si to Ei. Ci (0 <= Ci <= 10,000,000) is the maximum rate at which water will flow through the ditch.

     

    Output
    For each case, output a single integer, the maximum rate at which water may emptied from the pond.

     

    Sample Input
    5 4
    1 2 40
    1 4 20
    2 4 20
    2 3 30
    3 4 10

    Sample Output
    50

    基本照搬上道题.

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <map>
    #include <queue>
    using namespace std;
    int F[205][205];
    int p[205];
    bool f[205];
    int N, M, T;
    queue<int> q;
    int Edmond_Karp() {
        int ret = 0, u, MIN;
        while (1) {
            while (!q.empty()) {
                q.pop();
            }
            MIN = 0x7FFFFFFF;
            memset(f, false, sizeof(f));
            q.push(1);
            f[1] = true;
            while (!q.empty()) {
                u = q.front();
                q.pop();
                for (int i = 1; i <= N; i++) {
                    if (F[u][i] && !f[i]) {
                        q.push(i);
                        p[i] = u;
                        f[i] = true;
                    }
                }
            }
            if (!f[N]) {
                break;
            }
            for (int i = N; i != 1; i = p[i]) {
                if (F[p[i]][i] < MIN) {
                    MIN = F[p[i]][i];
                }
            }
            for (int i = N; i != 1; i = p[i]) {
                F[p[i]][i] -= MIN;
                F[i][p[i]] += MIN;
            }
            ret += MIN;
        }
        return ret;
    }
    int main() {
        int x, y, c;
        while (scanf("%d%d", &M, &N) != EOF) {
            memset(F, 0, sizeof(F));
            for (int i = 0; i < M; i++) {
                scanf("%d%d%d", &x, &y, &c);
                F[x][y] += c;
            }
            printf("%d
    ", Edmond_Karp());
        }
        return 0;
    }
    View Code

    HDU3572:Task Schedule
    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 7528 Accepted Submission(s): 2328

    Problem Description
    Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th task, the factory has to start processing it at or after day Si, process it for Pi days, and finish the task before or at day Ei. A machine can only work on one task at a time, and each task can be processed by at most one machine at a time. However, a task can be interrupted and processed on different machines on different days.
    Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.

    Input
    On the first line comes an integer T(T<=20), indicating the number of test cases.

    You are given two integer N(N<=500) and M(M<=200) on the first line of each test case. Then on each of next N lines are three integers Pi, Si and Ei (1<=Pi, Si, Ei<=500), which have the meaning described in the description. It is guaranteed that in a feasible schedule every task that can be finished will be done before or at its end day.

    Output
    For each test case, print “Case x: ” first, where x is the case number. If there exists a feasible schedule to finish all the tasks, print “Yes”, otherwise print “No”.

    Print a blank line after each test case.

    Sample Input
    2
    4 3
    1 3 5
    1 1 4
    2 3 7
    3 5 9

    2 2
    2 1 3
    1 2 2

    Sample Output
    Case 1: Yes

    Case 2: Yes

    这题略叼,首先构建一个流量网络,YY出来一个超级源点和一个超级汇点,并把每个工作和每一天作为节点加入。从超级源点出发创建n条弧指向n个工作,容量为其所需时间。从每个工作出发各创建相应数量的弧指向其对应的时间区间上的每个节点,容量为1。从每个时间节点出发创建一条弧指向超级汇点,容量为机器数。判断最大流是否等于所有的工作所需时间之和,若相等则可以按时完成,否则不能。

    这题用EK不行了,要用SAP。

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <map>
    #include <queue>
    using namespace std;
    const int SAP_INF = 0x7FFFFFFF;
    template <int N, int M> class ISAP {
    public:
        int top, edgeCnt;
        int d[N], pre[N], cur[N], gap[N];
        struct Vertex {
            int head;
        } V[N];
        struct Edge {
            int v, next;
            int c, f;
        } E[M];
        void init() {
            memset(V, -1, sizeof(V));
            top = 0;
            edgeCnt = 0;
        }
        void add_edge(int u, int v, int c) {
            E[top].v = v;
            E[top].c = c;
            E[top].f = 0;
            E[top].next = V[u].head;
            V[u].head = top++;
        }
        void add(int u, int v, int c) {
            add_edge(u, v, c);
            add_edge(v, u, 0);
            edgeCnt++;
        }
        void set_d(int t) {
            queue<int> Q;
            memset(d, -1, sizeof(d));
            memset(gap, 0, sizeof(gap));
            d[t] = 0;
            Q.push(t);
            while (!Q.empty()) {
                int v = Q.front();
                Q.pop();
                ++gap[d[v]];
                for (int i = V[v].head; ~i; i = E[i].next) {
                    int u = E[i].v;
                    if (d[u] == -1) {
                        d[u] = d[v] + 1;
                        Q.push(u);
                    }
                }
            }
        }
        int MaxFlow_SAP(int s, int t) {
            set_d(t);
            int ans = 0, u = s;
            int flow = SAP_INF;
            memcpy(cur, V, sizeof(V));
            while (d[s] < edgeCnt) {
                int &i = cur[u];
                for (; ~i; i = E[i].next) {
                    int v = E[i].v;
                    if (E[i].c > E[i].f && d[u] == d[v] + 1) {
                        u = v;
                        pre[v] = i;
                        flow = min(flow, E[i].c - E[i].f);
                        if (u == t) {
                            while (u != s) {
                                int j = pre[u];
                                E[j].f += flow;
                                E[j ^ 1].f -= flow;
                                u = E[j ^ 1].v;
                            }
                            ans += flow;
                            flow = SAP_INF;
                        }
                        break;
                    }
                }
                if (i == -1) {
                    if (--gap[d[u]] == 0) {
                        break;
                    }
                    int dmin = edgeCnt - 1;
                    cur[u] = V[u].head;
                    for (int j = V[u].head; ~j; j = E[j].next)
                        if (E[j].c > E[j].f) {
                            dmin = min(dmin, d[E[j].v]);
                        }
                    d[u] = dmin + 1;
                    ++gap[d[u]];
                    if (u != s) {
                        u = E[pre[u] ^ 1].v;
                    }
                }
            }
            return ans;
        }
    };
    ISAP<1005, 300000> Sap;
    int main() {
        int T, n, m, a, b, c, N, s;
        scanf("%d", &T);
        for (int o = 1; o <= T; o++) {
            Sap.init();
            s = 0;
            scanf("%d%d", &n, &m);
            N = n + 502;
            for (int i = n + 2; i <= n + 501; i++) {
                Sap.add(i, N, m);
            }
            for (int i = 1; i <= n; i++) {
                scanf("%d%d%d", &a, &b, &c);
                s += a;
                Sap.add(1, i + 1, a);
                for (int j = b; j <= c; j++) {
                    Sap.add(i + 1, n + 1 + j, 1);
                }
            }
            printf("Case %d: %s
    
    ", o, Sap.MaxFlow_SAP(1, N) == s ? "Yes" : "No");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    3.5星|津巴多《时间的悖论》:未来导向的人更有可能取得个人的成功,但帮助他人的可能性更小
    成功的销售必须在失败时也能快乐:4星|《哈佛商业评论》2018年第4期
    被取代的金融工作岗位越来越多:3星|《被人工智能操控的金融业》
    比特币和区块链是泡沫,但是短期内不会破:4星|《财经》2018年第7期
    点赞是当代可卡因:3星|《欲罢不能:刷屏时代如何摆脱行为上瘾》
    如何使用GetManifestResourceStream
    隐藏光标与获得光标2----获得光标所在的控件
    端口是否使用
    是否联网以及热点问题
    注册表操作
  • 原文地址:https://www.cnblogs.com/dramstadt/p/5964970.html
Copyright © 2011-2022 走看看