zoukankan      html  css  js  c++  java
  • cf- Educational Codeforces Round 40 -D

    题意:给你n个点,m条边,一个起点s,一个终点t的无向图,问在某两个点之间加一条边,不改变s到t的最短路径的值的加法有多少种,所有点一定连接;

    思路:首先,默认相邻两点的权值都为1,会改变值的情况有:

    从s出发,算出s的单源最短路dist,如果dist[x]+1<dist[t];

    从t出发,算出t的单源最短路Dist,如果Dist[x]+1<Dist[s];

    介于两点之间,s—t之间的某两个点之间+1<dist[s],也就是:dist[x]+Dist[y]+1<(Dist[s] | | dist[t]);

    所以从s跑一遍,再从t跑一遍最短路,然后遍历所有点,把能改变值的情况算出来;

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<cmath>
    #define maxn 100005
    const int inf=99999;
    using namespace std;
    struct Edge
    {
        int next;
        int to;
        int w;
    }edge[maxn];
    struct node
    {
        int num;
        int dist;
        node(int _num=0,int _dist=0):num(_num),dist(_dist){}
        friend bool operator<(node a,node b)
        {
            return a.dist>b.dist;
        }
    };
    int head[maxn];
    int s[maxn];
    int n,m,cnt;
    int dis[maxn];
    int dise[maxn];
    int disb[maxn];
    int book[1005][1005];
    //int book[maxn];
    bool vis[maxn];
    int be,en;
    void add(int u,int v,int w)
    {
        edge[cnt].next=head[u];
        edge[cnt].to=v;
        edge[cnt].w=w;
        head[u]=cnt++;
    }
    void dij(int x)
    {
        priority_queue<node>que;
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        dis[x]=0;
        que.push(node(x,0));
        while(!que.empty())
        {
            node p=que.top();
            que.pop();
            int now=p.num;
            if(vis[now])
                continue;
            vis[now]=true;
            for(int i=head[now];i!=-1;i=edge[i].next)
            {
                Edge e=edge[i];
                if(dis[e.to]>dis[now]+e.w&&!vis[e.to])
                {
                    dis[e.to]=dis[now]+e.w;
                    que.push(node(e.to,dis[e.to]));
                }
            }
        }
    }
    int main()
    {
        int x,y,w;
        cin>>n>>m>>be>>en;
            cnt=0;
            memset(book,0,sizeof(book));
            memset(head,-1,sizeof(head));
            for(int i=1;i<=m;i++)
            {
                cin>>x>>y;
                add(x,y,1);
                add(y,x,1);
            }
            int zz=0;
            int ans=0;
            for(int i=1;i<=n-1;i++)
                zz+=i;
            dij(en);
            for(int i=1;i<=n;i++)
                dise[i]=dis[i];
            dij(be);
            for(int i=1;i<=n;i++)
                disb[i]=dis[i];
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(i==j)
                        continue;
                    if(disb[i]+dise[j]+1<dise[be])
                    {
                        if(book[i][j]==0&&book[j][i]==0)
                        {
                            ans++;
                        }
                        book[i][j]=book[j][i]=1;
                    }
                    else if(disb[j]+1<dise[be]-1)
                    {
                        if(book[j][en]==0&&book[en][j]==0)
                            ans++;
                        book[j][en]=book[en][j]=1;
                    }
                    else if(dise[j]+1<disb[en])
                    {
                        if(book[be][j]==0&&book[j][en]==0)
                            ans++;
                        book[j][be]=book[be][j]=1;
                    }
                }
            }
           // cout<<ans<<endl;
            zz-=m;
            cout<<zz-ans<<endl;
        return 0;
    }
    

      

    ---恢复内容结束---

  • 相关阅读:
    Spring MVC,绑定数组、集合
    kettle 使用 CARTE 执行
    正交投影矩阵_相机中的透视投影几何——讨论相机中的正交投影
    VS 遇到异常 可能是某个扩展导致的 解决方法 和提升程序管理员权限的方法
    IDEA Community环境搭建笔记
    PHP ROT18加解密
    C# TTS 文字转语音
    软件开发文档【模板】
    java 打印日志 规范建议
    java 死锁 排查 (jstack jconsole jvisualvm jmc)
  • 原文地址:https://www.cnblogs.com/huangdao/p/8626675.html
Copyright © 2011-2022 走看看