博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
重要道路
阅读量:5063 次
发布时间:2019-06-12

本文共 3232 字,大约阅读时间需要 10 分钟。

题目描述

给定一个无向图 G,对于其中的一条边(u,v),将它删除之后会使得从 1 到 n
的最短路长度增加,那么这条边被称为“重要道路”。
求 G 中所有的重要道路。
输入格式
第一行两个整数 n,m,分别代表点数和边数。
接下来 m 行,每行三个整数 u,v,c,代表权值为 c 的无向边(u,v)。可能有重
边,但没有自环。保证 1 号点和 n 号点是连通的。
输出格式
第一行一个整数 k,代表重要道路的数量。
下一行升序输出 k 个数代表重要道路的编号(按输入顺序从 1 到 m)。
输入样例
6 7
1 2 1
2 3 1
2 5 3
1 3 2
3 5 1
2 4 1
5 6 2
输出样例
2
5 7

数据规模

20%的数据,n,m<=10。
另外 20%的数据,m=n-1。
100%的数据,1<=n<=20000,1<=m,c<=100000。

SPFA求最短路

求出所有在最短路上的边

求出这些边的割边(桥)

此题卡SPFA,要用单调队列优化

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 using namespace std; 8 struct Node 9 { 10 int next,to,dis,id; 11 }edge[400001]; 12 struct Edge 13 { 14 int u,v,w; 15 }e[200001]; 16 struct ZYYS 17 { 18 int x,d; 19 bool operator < (const ZYYS &a) 20 const 21 { 22 return d>a.d; 23 } 24 }; 25 int dist[200001],vis[200001],head[200001],num,ban[200001],n,m,d,ans,a[200001],dist2[200001]; 26 int dfn[200001],low[200001],cnt,instack[200001]; 27 void add(int u,int v,int dis,int id) 28 { 29 num++; 30 edge[num].next=head[u]; 31 head[u]=num; 32 edge[num].to=v; 33 edge[num].dis=dis; 34 edge[num].id=id; 35 } 36 void SPFA() 37 { int i; 38 priority_queue
Q; 39 for (i=1;i<=n;i++) 40 vis[i]=0,dist[i]=1e9; 41 dist[1]=0; 42 Q.push((ZYYS){ 1,0}); 43 while (Q.empty()==0) 44 { 45 ZYYS u=Q.top(); 46 Q.pop(); 47 vis[u.x]=0; 48 for (i=head[u.x];i;i=edge[i].next) 49 if (ban[i]==0) 50 { 51 int v=edge[i].to; 52 if (dist[v]>dist[u.x]+edge[i].dis) 53 { 54 dist[v]=dist[u.x]+edge[i].dis; 55 if (vis[v]==0) 56 { 57 vis[v]=1; 58 Q.push((ZYYS){v,dist[v]}); 59 } 60 } 61 } 62 } 63 } 64 void SPFA2() 65 { int i; 66 priority_queue
Q; 67 for (i=1;i<=n;i++) 68 dist2[i]=1e9,vis[i]=0; 69 dist2[n]=0; 70 Q.push((ZYYS){n,0}); 71 while (Q.empty()==0) 72 { 73 ZYYS u=Q.top(); 74 Q.pop(); 75 vis[u.x]=0; 76 for (i=head[u.x];i;i=edge[i].next) 77 if (ban[i]==0) 78 { 79 int v=edge[i].to; 80 if (dist2[v]>dist2[u.x]+edge[i].dis) 81 { 82 dist2[v]=dist2[u.x]+edge[i].dis; 83 if (vis[v]==0) 84 { 85 vis[v]=1; 86 Q.push((ZYYS){v,dist[v]}); 87 } 88 } 89 } 90 } 91 } 92 void dfs(int x,int pa) 93 { int flag=0,i; 94 dfn[x]=low[x]=++cnt; 95 instack[x]=1; 96 flag=0; 97 for (i=head[x];i;i=edge[i].next) 98 { 99 int v=edge[i].to;100 if (flag==0&&v==pa)101 {102 flag=1;continue;103 }104 if (dfn[v]==0)105 {106 dfs(v,x);107 low[x]=min(low[v],low[x]);108 if (low[v]>dfn[x]) vis[edge[i].id]=1,ans++;109 }110 else if (instack[v]) low[x]=min(low[x],dfn[v]);111 }112 instack[x]=0;113 }114 int main()115 { int i,u,v,w,j;116 freopen("important.in","r",stdin);117 freopen("important.out","w",stdout);118 cin>>n>>m;119 for (i=1;i<=m;i++)120 {121 scanf("%d%d%d",&u,&v,&w);122 e[i].u=u,e[i].v=v,e[i].w=w;123 add(u,v,w,i);124 add(v,u,w,i);125 }126 SPFA();127 SPFA2();128 memset(vis,0,sizeof(vis));129 for (i=1;i<=n;i++)130 {131 for (j=head[i];j;j=edge[j].next)132 {133 int v=edge[j].to;134 if (dist[i]+edge[j].dis+dist2[v]==dist[n])135 {136 vis[(j+1)/2]=1;137 }138 }139 }140 memset(head,0,sizeof(head));141 num=0;142 for (i=1;i<=m;i++)143 if (vis[i]) add(e[i].u,e[i].v,e[i].w,i),add(e[i].v,e[i].u,e[i].w,i);144 memset(vis,0,sizeof(vis));145 dfs(1,0);146 cout<
<

 

转载于:https://www.cnblogs.com/Y-E-T-I/p/8602616.html

你可能感兴趣的文章
【蓝桥杯】PREV-21 回文数字
查看>>
html 简介
查看>>
python使用上下文对代码片段进行计时,非装饰器
查看>>
js中比较实用的函数用法
查看>>
安装预览版镜像后无法检测到预览版更新的解决方案
查看>>
【bzoj5099】[POI2018]Pionek 双指针法
查看>>
别让安全问题拖慢了 DevOps!
查看>>
JAR打包和运行
查看>>
session如何保存在专门的StateServer服务器中
查看>>
react展示数据
查看>>
测试计划
查看>>
idea设置自定义图片
查看>>
[高级]Android多线程任务优化1:探讨AsyncTask的缺陷
查看>>
选择器
查看>>
rownum 的使用
查看>>
Mysql与Oracle 的对比
查看>>
MVC系列博客之排球计分(三)模型类的实现
查看>>
npm安装
查看>>
阅读笔记02
查看>>
2019年春季学期第二周作业
查看>>