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 }