CodeForces - 449B 最短路(迪杰斯特拉+堆优化)判断最短路路径数

题意:

给出n个点m条公路k条铁路。

接下来m行

u v w      //u->v 距离w

然后k行

v w         //1->v 距离w

如果修建了铁路并不影响两点的最短距离,那么修铁路是没必要的

求能删掉多少条铁路

 

题解:

把公路和铁路放一起构成一个图,然后跑一边最短路。最后如果最短路结果小于铁路的长度,那么这条铁路就没必要修

如果最短路结果等于铁路的长度,要先判断一下这个最短路是不是一条,如果这条最短路个数多于一条那么这条铁路就没必要修

 

怎么判断最短路路径数是不是大于1?

 1 while(!r.empty())
 2     {
 3         str1=r.top();
 4         r.pop();
 5         int u=str1.v;
 6         if(vis[u]) continue;
 7         vis[u]=1;
 8         for(int i=head[u]; i!=-1; i=e[i].nex)
 9         {
10             int v=e[i].v;
11             int a=e[i].a;
12             if(dis[v]>a+dis[u])
13             {
14                 in[v]=1;
15                 dis[v]=a+dis[u];
16                 r.push(shudui1(v,dis[v]));
17             }
18             else if(dis[v]==a+dis[u])
19             {
20                 in[v]++;
21             }
22         }
23     }

这个in数组就是来判断,从起点1到终点i的最短路路径数的数量

 

代码:

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<vector>
  7 #include<math.h>
  8 using namespace std;
  9 const int INF=0x3f3f3f3f;
 10 const int maxn=1e5+5;
 11 typedef long long ll;
 12 const ll MAX=1e17;
 13 const ll inf=(ll)1<<61;
 14 struct shudui1
 15 {
 16     int v,c;
 17     shudui1(int x=0,int y=0):v(x),c(y) {}
 18     bool operator < (const shudui1 q)const
 19     {
 20         return c>q.c;
 21     }
 22 } str1;
 23 struct node
 24 {
 25     int a,v,nex;
 26 } e[maxn*20];
 27 int tot,dis[maxn],p[70],vis[maxn],head[maxn],in[maxn],x[maxn],y[maxn];
 28 int n,m,k;
 29 void add(int u,int v,int a)
 30 {
 31     e[tot].v=v,e[tot].a=a;
 32     e[tot].nex=head[u];
 33     head[u]=tot++;
 34     //printf("%d %d\n",tot-1,v);
 35 }
 36 priority_queue<shudui1>r; //里面的数据默认是从小到大排序,这样就不用通过for循环遍历在每一次找v里面的最小值,可以直接找到最小值,减少代码运行次数
 37 int JK(int s)
 38 {
 39     memset(dis,INF,sizeof(dis));
 40     memset(vis,0,sizeof(vis));
 41     dis[s]=0;
 42     str1.v=s;
 43     str1.c=0;
 44     r.push(str1);
 45     while(!r.empty())
 46     {
 47         str1=r.top();
 48         r.pop();
 49         int u=str1.v;
 50         if(vis[u]) continue;
 51         vis[u]=1;
 52         for(int i=head[u]; i!=-1; i=e[i].nex)
 53         {
 54             int v=e[i].v;
 55             int a=e[i].a;
 56             if(dis[v]>a+dis[u])
 57             {
 58                 in[v]=1;
 59                 dis[v]=a+dis[u];
 60                 r.push(shudui1(v,dis[v]));
 61             }
 62             else if(dis[v]==a+dis[u])
 63             {
 64                 in[v]++;
 65             }
 66         }
 67     }
 68 //    for(int i=1;i<=n;++i)
 69 //        printf("%d\n",dis[i]);
 70     int ans=0;
 71     for(int i=1;i<=k;++i)
 72     {
 73         if(dis[x[i]]<y[i]) ans++;
 74         else if(dis[x[i]]==y[i] && in[x[i]]>1)
 75         {
 76             in[x[i]]--;
 77             ans++;
 78         }
 79 
 80     }
 81     return ans;
 82 }
 83 int main()
 84 {
 85     scanf("%d%d%d",&n,&m,&k);
 86     for(int i=0; i<=n; i++)
 87     {
 88         dis[i]=INF;
 89     }
 90     memset(head,-1,sizeof(head));
 91     for(int i=1; i<=m; i++)
 92     {
 93         int u,v,w;
 94         scanf("%d %d %d",&u,&v,&w);
 95         add(u,v,w);
 96         add(v,u,w);
 97     }
 98     for(int i=1; i<=k; i++)
 99     {
100         int v,w;
101         scanf("%d %d",&x[i],&y[i]);
102         add(1,x[i],y[i]);
103         add(x[i],1,y[i]);
104     }
105     cout<<JK(1)<<endl;
106     return 0;
107 }

 

posted @ 2020-05-01 11:37  kongbursi  阅读(202)  评论(0编辑  收藏  举报