您的位置:首页 > 其它

ACdream 1415 最短路+桥

2016-06-19 15:13 253 查看
点击打开链接

题意:给个图,问你从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
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: