Gym - 101666D Detour

题意:给定n个点,m条边,起点为0,终点为1。对于路径上除终点外的每一个点,其到终点1的最短路径上都有一个标志,问是否能在绕开标志的情况下找到一条从0到1的路径,存在的话打印路径。

大致思路是将有标志的边删掉,然后dfs看0到1是否连通。
问题的重点在于如何快速优雅地找到有标志的边。

从题意中可以看到,所有的标志都是到1的最短路上的标志,所以可以把1做为源点,跑最短路。dfs的时候判断一下边的两个端点u和v是否满足dist[u]=dist[v]+weight[u][v],若满足,则该边不通。

没什么坑点,直接贴代码

#include <bits/stdc++.h>
#define N 100010
#define LL long long
#define INF 0x3f3f3f3f3f
using namespace std;
typedef pair<LL,int>pa;
vector<pa>edge[N];

LL dis[N];
int path[N],vis[N],flag=0;
void dijkstra(int x){
    memset(dis,INF, sizeof(dis));
    priority_queue<pa,vector<pa>,greater<pa> >qu;
    qu.push(pa(0,x));
    dis[x]=0;
    while(!qu.empty()){
        pa u=qu.top();
        qu.pop();
        for(int i=0;i<edge[u.second].size();i++){
            int v=edge[u.second][i].second;
            LL w=edge[u.second][i].first;
            if(w+u.first<dis[v]){
                dis[v]=w+u.first;
                qu.push(pa(dis[v],v));
            }
        }
    }
}
void dfs(int x){
    if(x==1){
        flag=1;
        return;
    }
    for(int i=0;i<edge[x].size();i++){
        int v=edge[x][i].second;
        if(dis[x]==dis[v]+edge[x][i].first)
            continue;
        if(!vis[v]){
            vis[v]=1;
            path[x]=v;
            dfs(v);
        }
        if(flag)//如果找到从0到1的路径即退出dfs
            return;
    }
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    int u,v;
    LL w;
    for(int i=0;i<m;i++){
        scanf("%d%d%lld",&u,&v,&w);
        edge[u].push_back(pa(w,v));
        edge[v].push_back(pa(w,u));
    }
    dijkstra(1);
    vis[0]=1;
    memset(path,-1, sizeof(path));
    dfs(0);
    if(flag){
        vector<int>ans;
        int x=0;
        while(x!=-1){
            ans.push_back(x);
            x=path[x];
        }
        printf("%d",ans.size());
        for(int i=0;i<ans.size();i++)
            printf(" %d",ans[i]);
        printf("\n");
    } else
        printf("impossible\n");
    return 0;
}

懒惰如我竟然开始写题解。其实只是因为很久没写最短路,mark一下dijkstra的板子233333。

猜你喜欢

转载自blog.csdn.net/vermouth_x/article/details/79855456
今日推荐