• 2013多校第四场 G题 ZZ的搬砖难题


    虽然题目只给了起点st,和终点ed,  st,ed <= 10000.

    但是只有200条边,极端情况也才200条边对应的400个顶点都不一样.

    所以我们可以离散化顶点到[1,400]之间.然后跑个最大流即可.

    注意本题边是单向的.

    View Code
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<map>
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const int MAXN = 1e5+10;
    #define MIN(a,b) (a)<(b)?(a):(b)
    #define MAX(a,b) (a)>(b)?(a):(b)
    int k, c, m, s, t, n, N;
    int head[MAXN], idx, vh[MAXN], h[MAXN];
    struct node{
        int v, f, nxt;
    }edge[MAXN];
    
    struct Tmp{
        int u, v, c;
        void input(){
            scanf("%d%d%d", &u,&v,&c);    
        }    
    }test[210];
    map<int,int> mp;
    int st, ed;
    
    void AddEdge( int u, int v, int f )
    {
        edge[idx].v = v; edge[idx].f = f;
        edge[idx].nxt = head[u]; head[u] = idx++;
        edge[idx].v = u; edge[idx].f = 0;
        edge[idx].nxt = head[v]; head[v] = idx++;
    }
    
    void input() 
    {
        scanf("%d", &m);
        int cnt = 0;
        mp.clear();    
        if( mp.count(st) == 0 ) mp[st] = ++cnt;
        if( mp.count(ed) == 0 ) mp[ed] = ++cnt;
        for(int i = 0; i < m; i++){
            test[i].input();
            if( mp.count( test[i].u ) == 0 ) mp[ test[i].u ] = ++cnt;
            if( mp.count( test[i].v ) == 0 ) mp[ test[i].v ] = ++cnt;
        }
        N = cnt;
        memset( head, 0xff, sizeof(head) ); idx = 0;
        s = mp[st]; t = mp[ed];
        for(int i = 0; i < m; i++){
            AddEdge( mp[test[i].u], mp[test[i].v], test[i].c );
            AddEdge( mp[test[i].v], mp[test[i].u], test[i].c );
        }
    //    AddEdge( s, mp[st], inf );
    //    AddEdge( mp[ed], t, inf );
    }
    int DFS(int u,int flow )
    {
        if( u == t ) return flow;
        int tmp = h[u]+1, remain = flow;
        for(int i = head[u]; ~i; i = edge[i].nxt )
        {
            int v = edge[i].v;
            if( edge[i].f && h[u] == h[v]+1 )
            {
                int p = DFS( v, MIN( remain, edge[i].f ));
                edge[i].f -= p; edge[i^1].f += p; remain -= p;
                if( remain == 0 || h[s] == N ) return flow-remain;
            }
        }
        for(int i = head[u]; ~i; i = edge[i].nxt )
            if( edge[i].f ) tmp = MIN( tmp, h[ edge[i].v ] );
        if( !( --vh[ h[u] ] ) ) h[s] = N;
        else    ++vh[ h[u] = tmp+1 ];
        return flow-remain;
    }
    int sap()
    {
        int maxflow = 0;
        memset( h, 0, sizeof(h));
        memset( vh, 0, sizeof(vh));
        vh[0] = N;
        while( h[s] < N ) maxflow += DFS( s, inf );
        return maxflow;
    }
    int main()
    {
        while( scanf("%d%d", &st, &ed ) != EOF)
        {
            input();
            int res = sap();    
            printf("%d\n", res ); 
        }
        return 0;
    }
  • 相关阅读:
    新安装的CentOS 7不能上网
    修改机器名
    读书笔记-MySQL运维内参08-索引实现原理2
    读书笔记-MySQL运维内参08-索引实现原理1
    读书笔记-MySQL运维内参07-InnoDB数据存储结构
    MySQL 参数设置-持续更新
    读书笔记-Mycat权威指南-10-分片规则
    读书笔记-Mycat权威指南-09-全局序列号
    读书笔记-Mycat权威指南-08-Mycat中的Join
    读书笔记-Mycat权威指南-03-Mycat中的概念
  • 原文地址:https://www.cnblogs.com/yefeng1627/p/3049824.html
Copyright © 2020-2023  润新知