点击打开链接
题意:给个图,问你从1到n的最短路的路径上,有多少桥
思路:先是要满足条件最短路,然后判断每条边是不是最短路里的边,怎么判断也很简单,先从1开始求最短路和从n开始求最短路,对于边U到V来说,若1到U的最短路加上n到V的最短路在加上这条边的权值若等于1到n的最短路,那么这条边就是我们要的,就是这个条件if(dis1[U[i]]+COST[i]+dis2[V[i]]==maxdis||dis1[V[i]]+COST[i]+dis2[U[i]]==maxdis)maxdis是1到n的最短路长度,然后题目说了可能有重边,好处理,之前做题时队友跟我讲题意说没有重边,WA了好久,然后将边的id和个数找到输出就行了,只是模版的应用而已,不难的~~~
#include <queue> #include <vector> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const ll inf=0x3f3f3f3f3f3f3f3fll; const int maxn=20010; struct edge{ int to,cost; edge(){} edge(int a,int b){to=a;cost=b;} }; typedef pair<int,long long>P; vector<edge>G[maxn]; ll dis1[maxn],dis2[maxn]; void dijkstra(int st,ll dis[]){ priority_queue<P,vector<P>,greater<P> >que; fill(dis,dis+maxn,inf); dis[st]=0; que.push(P(0,st)); while(!que.empty()){ P p=que.top();que.pop(); int v=p.second; if(dis[v]<p.first) continue; for(unsigned int i=0;i<G[v].size();i++){ edge e=G[v][i]; if(dis[e.to]>dis[v]+(ll)e.cost){ dis[e.to]=dis[v]+(ll)e.cost; que.push(P(dis[e.to],e.to)); } } } } int U[100010],V[100010],COST[100010]; struct edge1{ int to,id,num; edge1(int a,int b,int c){to=a;id=b;num=c;} }; vector<edge1>GG[maxn]; int L[maxn],E[maxn],ans[maxn],vis[maxn],stack1[maxn]; int k,kk,cnt,n,m; void dfs(int x,int fa){ vis[x]=1;L[x]=k;E[x]=k++;stack1[kk++]=x; int flag=0; for(unsigned int i=0;i<GG[x].size();i++){ edge1 e=GG[x][i]; if(e.to!=fa){ if(!vis[e.to]){ dfs(e.to,x); L[x]=min(L[x],L[e.to]); if(L[e.to]>E[x]) GG[x][i].num=1; }else L[x]=min(L[x],E[e.to]); }else{ if(flag) L[x]=min(L[x],E[e.to]); flag++; } } if(L[x]==E[x]){ while(stack1[kk]!=x&&kk>0){ L[stack1[kk-1]]=L[x]; kk--; vis[stack1[kk]]=0; } } } void tarjan(){ kk=0;k=1;dfs(1,1); cnt=0; for(int i=1;i<=n;i++){ for(unsigned int j=0;j<GG[i].size();j++){ edge1 e=GG[i][j]; if(L[i]!=L[e.to]&&e.num==1){ ans[cnt++]=e.id; } } } } int main(){ while(scanf("%d%d",&n,&m)!=-1){ for(int i=0;i<maxn;i++) G[i].clear(); for(int i=0;i<maxn;i++) GG[i].clear(); for(int i=0;i<m;i++){ scanf("%d%d%d",&U[i],&V[i],&COST[i]); G[U[i]].push_back(edge(V[i],COST[i])); G[V[i]].push_back(edge(U[i],COST[i])); } dijkstra(1,dis1); dijkstra(n,dis2); ll maxdis=dis1[n]; for(int i=0;i<m;i++){ if(dis1[U[i]]+COST[i]+dis2[V[i]]==maxdis||dis1[V[i]]+COST[i]+dis2[U[i]]==maxdis){ GG[U[i]].push_back(edge1(V[i],i+1,0)); GG[V[i]].push_back(edge1(U[i],i+1,0)); } } tarjan(); printf("%d\n",cnt); sort(ans,ans+cnt); for(int i=0;i<cnt-1;i++) printf("%d ",ans[i]); printf("%d\n",ans[cnt-1]); } return 0; }