zoukankan      html  css  js  c++  java
  • Cow and Fields

    题目链接:http://codeforces.com/contest/1307/problem/D

    题意:有n个点,m条边,n个点里有k个特殊的点,现在你要在两个特殊的点之间加一条边(不管之前是否有边),加完边后要让1号点到n号点的最短路径及可能的长

    思路:我们可以先求出所有特殊的点到点1和点x的距离,特殊点i到点1的距离为xi ,到点n的距离为yi。然后选择两个字段 aaa 和 bbb 来最大化min(xa+yb,ya+xb)。

             然后再按xi-yi从小到大排序就可以了。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<math.h>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<map>
    typedef long long ll;
    using namespace std;
    const int Inf=999999999;
    int n,m,k;
    struct node
    {
        int v,w;//后继结点与权值
        node() {}
        node(int vv,int ww)
        {
            v=vv;
            w=ww;
        }
    };
    struct Node
    {
        int u,w;//前驱结点与权值
        Node() {}
        Node(int uu,int ww)
        {
            u=uu;
            w=ww;
        }
        bool operator<(const Node other)const
        {
            return w>other.w;
        }
    };
    struct nd
    {
        int l,r,v;
    } aa[200005];
    bool cmp(nd a,nd b)
    {
        return a.v<b.v;
    }
    const int N=200005;
    int book[N],dis[N],vv[N],bookk[N],dis1[N],mm[N],cc[N];
    vector<node> G[N];
    void Dijkstra()
    {
        priority_queue<Node> p;
        memset(book,0,sizeof(book));
        for(int i=1; i<=n; i++)
            dis[i]=Inf;
        dis[1]=0;
        p.push(Node(1,dis[1]));
        while(!p.empty())
        {
            Node temp=p.top();
            p.pop();
            int u=temp.u;
            if(book[u])
                continue;
            book[u]=1;
            for(int i=0; i<G[u].size(); i++)
            {
                node tv=G[u][i];
                int v=tv.v;
                int w=tv.w;
                if(dis[v]>dis[u]+w)
                {
                    dis[v]=dis[u]+w;
                    p.push(Node(v,dis[v]));
                }
            }
        }
    }
    void Dijkstra1()
    {
        priority_queue<Node> p;
        memset(bookk,0,sizeof(bookk));
        for(int i=1; i<=n; i++)
            dis1[i]=Inf;
        dis1[n]=0;
        p.push(Node(n,dis1[n]));
        while(!p.empty())
        {
            Node temp=p.top();
            p.pop();
            int u=temp.u;
            if(bookk[u])
                continue;
            bookk[u]=1;
            for(int i=0; i<G[u].size(); i++)
            {
                node tv=G[u][i];
                int v=tv.v;
                int w=tv.w;
                if(dis1[v]>dis1[u]+w)
                {
                    dis1[v]=dis1[u]+w;
                    p.push(Node(v,dis1[v]));
                }
            }
        }
    }
    int main()
    {
    
        while(~scanf("%d%d%d",&n,&m,&k))
        {
            for(int i=1; i<=k; i++)
            {
    
                scanf("%d",&mm[i]);
                vv[mm[i]]=1;
            }
            int u,v,w;
            bool ff=0;
            while(m--)
            {
                scanf("%d%d",&u,&v);
                if(vv[u]&&vv[v])
                    ff=1;
                G[u].push_back(node(v,1));
                G[v].push_back(node(u,1));
            }
            Dijkstra();
            Dijkstra1();
            if(ff)
                printf("%d
    ",dis[n]);
            else
            {
                int cnt=0;
                for(int i=1; i<=k; i++)
                {
                    aa[++cnt].l=dis[mm[i]];
                    aa[cnt].r=dis1[mm[i]];
                    aa[cnt].v=aa[cnt].l-aa[cnt].r;
                }
                sort(aa+1,aa+k+1,cmp);
                int Max=0;
                for(int i=k; i>=1; i--)
                {
                    cc[i]=max(aa[i].r,Max);
                }
                Max=0;
                for(int i=1; i<k; i++)
                {
                    Max=max(Max,aa[i].l+cc[i+1]);
                }
                if(Max+1>dis[n])
                    printf("%d
    ",dis[n]);
                else
                    printf("%d
    ",Max+1);
            }
        }
        return 0;
    }

     

  • 相关阅读:
    PAT顶级 1024 Currency Exchange Centers (35分)(最小生成树)
    Codeforces 1282B2 K for the Price of One (Hard Version)
    1023 Have Fun with Numbers (20)
    1005 Spell It Right (20)
    1092 To Buy or Not to Buy (20)
    1118 Birds in Forest (25)
    1130 Infix Expression (25)
    1085 Perfect Sequence (25)
    1109 Group Photo (25)
    1073 Scientific Notation (20)
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/12329140.html
Copyright © 2011-2022 走看看