• SPOJ NETADMIN


    NETADMIN - Smart Network Administrator

    The citizens of a small village are tired of being the only inhabitants around without a connection to the Internet. After nominating the future network administrator, his house was connected to the global network. All users that want to have access to the Internet must be connected directly to the admin's house by a single cable (every cable may run underground along streets only, from the admin's house to the user's house). Since the newly appointed administrator wants to have everything under control, he demands that cables of different colors should be used. Moreover, to make troubleshooting easier, he requires that no two cables of the same color go along one stretch of street.

    Your goal is to find the minimum number of cable colors that must be used in order to connect every willing person to the Internet.

    Input

    t [the number of test cases, t<=500]
    n m k [n <=500 the number of houses (the index of the admin's house is 1)]
    [m the number of streets, k the number of houses to connect]
    h1 h2 ... hk [a list of k houses wanting to be conected to the network, 2<=hi<=n]
    [The next m lines contain pairs of house numbers describing street ends]
    e11 e12
    e21 e22
    ...
    em1 em2
    [next cases]

    Output

    For each test case print the minimal number of cable colors necessary to make all the required connections.

    Example

    Input:
    2
    5 5 4
    2 3 4 5
    1 2
    1 3
    2 3
    2 4
    3 5
    8 8 3
    4 5 7
    1 2
    1 8
    8 7
    1 3
    3 6
    3 2
    2 4
    2 5
    
    Output:
    2
    1
    

    Illustration to the first example

    Warning: large Input/Output data, be careful with certain languages
    【分析】颜色数相当于限定了经过每条边的cable数的上界,考虑二分答案res,现在要判定是否存在一系列从1出发分别到2,3,…,n的路径,使得经过每条边的路径数不超过res,一条路径就是一条流,建图跑最大流即可。
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <map>
    #include <stack>
    #include <queue>
    #include <vector>
    #define inf 0x3f3f3f3f
    #define met(a,b) memset(a,b,sizeof a)
    #define pb push_back
    typedef long long ll;
    using namespace std;
    const int N = 2e3+10;
    const int M = 24005;
    int n,m,k,f,d;
    struct Edge{
        int from,to,cap,flow;
        Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
    };
    struct Dinic{
        int s,t;
        vector<Edge>edges;
        vector<int> G[N];
        bool vis[N];
        int d[N];
        int cur[N];
        void init(){
           for (int i=0;i<=n+1;i++)
               G[i].clear();
           edges.clear();
        }
        void AddEdge(int from,int to,int cap){
            edges.push_back(Edge(from,to,cap,0));
            edges.push_back(Edge(to,from,0,0));
            int mm=edges.size();
            G[from].push_back(mm-2);
            G[to].push_back(mm-1);
        }
        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];
        }
    
        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 s,int t){
            this->s=s;
            this->t=t;
            int flow = 0;
            while (BFS()){
                memset(cur,0,sizeof(cur));
                flow+=DFS(s,inf);
            }
            return flow;
        }
    }dc;
    int main(){
        int T,u,v;
        scanf("%d",&T);
        while(T--){
    
            vector<int>vec,edg;
            scanf("%d%d%d",&n,&m,&k);
            for(int i=0;i<k;i++){
                scanf("%d",&u);
                vec.pb(u);
            }
            while(m--){
                scanf("%d%d",&u,&v);
                edg.push_back(u);edg.push_back(v);
            }
            int l=0,r=n,ans=0;
            while(l<=r){
                int mid=(l+r)/2;
                dc.init();
                for(int i=0;i<edg.size();i+=2){
                    u=edg[i];v=edg[i+1];
                    dc.AddEdge(u,v,mid);
                    dc.AddEdge(v,u,mid);
                }
                for(int i=0;i<vec.size();i++){
                    u=vec[i];
                    dc.AddEdge(0,u,1);
                }
                if(dc.Maxflow(0,1)==k)r=mid-1,ans=mid;
                else l=mid+1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    创建XNA Shooter游戏——概述
    Android 界面切换与恢复原生界面
    输入和用户界面——SpaceCamera类
    ASP.NET下FCKedit配置及使用参考
    1282. Game Tree 夜
    1122. Game 夜
    1136. Parliament 夜
    hdu 3905 Sleeping 夜
    1195. Ouths and Crosses 夜
    1210. Kind Spirits 夜
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6446184.html
Copyright © 2020-2023  润新知