码迷,mamicode.com
首页 > 其他好文 > 详细

ACdream 1415 最短路+桥

时间:2016-06-21 07:12:05      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:

点击打开链接

题意:给个图,问你从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;
}

ACdream 1415 最短路+桥

标签:

原文地址:http://blog.csdn.net/dan__ge/article/details/51712452

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!