zoukankan      html  css  js  c++  java
  • CDOJ UESTC 1220 The Battle of Guandu

    The 2015 China Collegiate Programming Contest

    2015第一届中国大学生程序设计竞赛 F题

    本质就是求单源最短路!注意会爆int

    对于每一个村庄i,其实就是花费c[i],把一个人从y[i]转移到x[i];

    如果一张图中,不存在w[i]==2的节点,那么花费肯定是0。

    所以,花费就出在w[i]==2的节点上,怎么处理这些节点呢?

    可以从w[i]==0的节点上流出一些人,流到w[i]==2的节点上,并且对于每个w[i]==2的节点只需要一个人。

    因此,设立一个节点S,连向所有w[i]==0的节点,费用为0;

    对于每一个村庄i,从y[i]到x[i]连边,费用为c[i];

    然后从S出发,跑单源最短路,最终把S到w[i]==2的节点的最短路都加起来就是答案。

    如果有一个w[i]==2的节点不能到达,那么就输出-1.

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    const long long INF=10000000000;
    const int maxn=300000+10;
    int T,N,M;
    int x[maxn],y[maxn];
    long long c[maxn];
    int w[maxn];
    
    vector<int>G[maxn];
    queue<int>Q;
    bool flag[maxn];
    long long dis[maxn];
    
    struct Edge
    {
        int from,to;
        long long cost;
    } e[maxn];
    int tot;
    
    void init()
    {
        for(int i=0; i<maxn; i++) G[i].clear();
        if(!Q.empty()) Q.pop();
        for(int i=0; i<maxn; i++) dis[i]=INF;
        memset(flag,0,sizeof flag);
    }
    
    void add(int x,int y,long long c)
    {
        tot++;
        e[tot].from=x;
        e[tot].to=y;
        e[tot].cost=c;
        G[x].push_back(tot);
    }
    
    void read()
    {
        tot=0;
        init();
        scanf("%d%d",&N,&M);
        for(int i=1; i<=N; i++) scanf("%d",&x[i]);
        for(int i=1; i<=N; i++) scanf("%d",&y[i]);
        for(int i=1; i<=N; i++) scanf("%lld",&c[i]);
        for(int i=1; i<=M; i++) scanf("%d",&w[i]);
    
        for(int i=1; i<=N; i++) add(y[i],x[i],c[i]);
        for(int i=1; i<=M; i++)
        {
            if(w[i]==0) add(0,i,0);
            else if(w[i]==2) add(i,M+1,0);
        }
    }
    
    void spfa()
    {
        flag[0]=1;
        Q.push(0);
        dis[0]=0;
        while(!Q.empty())
        {
            int h=Q.front();
            Q.pop();
            flag[h]=0;
            for(int i=0; i<G[h].size(); i++)
            {
                int id=G[h][i];
                if(dis[h]+e[id].cost<dis[e[id].to])
                {
                    dis[e[id].to]=dis[h]+e[id].cost;
                    if(!flag[e[id].to])
                    {
                        flag[e[id].to]=1;
                        Q.push(e[id].to);
                    }
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d",&T);
        for(int Case=1; Case<=T; Case++)
        {
            read();
            spfa();
            long long ans=0;
            for(int i=1; i<=M; i++)
            {
                if(w[i]==2)
                {
                    if(dis[i]==INF)
                    {
                        ans=-1;
                        break;
                    }
                    ans=ans+dis[i];
                }
            }
            printf("Case #%d: %lld
    ",Case,ans);
        }
        return 0;
    }
  • 相关阅读:
    [20180808]exists and not exists.txt
    [20180806]tune2fs调整保留块百分比.txt
    [20180730]exadata与行链接.txt
    [20180801]insert导致死锁.txt
    [20180718]拷贝数据文件从dg库.txt
    [20180713]关于hash join 测试中一个疑问.txt
    [20180705]关于hash join 2.txt
    virtualbox 中ubantu虚拟机范文win7文件夹
    myeclipse10安装findbugs
    win7共享文件夹给局域网
  • 原文地址:https://www.cnblogs.com/zufezzt/p/4913154.html
Copyright © 2011-2022 走看看