• 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;
    }

     

  • 相关阅读:
    CodeForces 347B Fixed Points (水题)
    CodeForces 347A Difference Row (水题)
    CodeForces 346A Alice and Bob (数学最大公约数)
    CodeForces 474C Captain Marmot (数学,旋转,暴力)
    CodeForces 474B Worms (水题,二分)
    CodeForces 474A Keyboard (水题)
    压力测试学习(一)
    算法学习(一)五个常用算法概念了解
    C#语言规范
    异常System.Threading.Thread.AbortInternal
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/12329140.html
Copyright © 2020-2023  润新知