CSU1092-Barricade-最短路/Dijkstra

来源:互联网 发布:针织短款开衫淘宝网 编辑:程序博客网 时间:2024/06/02 05:48

D: Barricade

Description

GBQC国一共有N个城市,标号分别为1, 2, …, N。N个城市间一共有M条单向通行的道路。

不幸的是,GBQC国的城市1连续暴雨,使得整个城市淹没在汪洋洪水中,于是GBQC国领导人小明决定让城市1的居民暂时移居到城市N,于是一场浩浩荡荡的搬迁运动开始了。

但还有一个问题需要解决,居民从城市1出发,如果走到某个城市时面对多条道路,那么城市1的居民就不知道该往哪个方向走了。

为了解决上述问题,GBQC国领导人决定在一些道路的入口处设置“禁止通行”的路障,以确保城市1的居民从城市1出发,途径每个城市时,都有且仅有一条路可供选择,这样城市1的居民就能顺利搬迁到城市N了。

​ 现在GBQC国领导人想知道最少需要设置几个路障呢?

Input

输入包含多组测试数据。

对于每组测试数据,第一行包含两个整数N(2<=N<=10^4), M(0<=M<=10^5),其中N、M的含义同上。接下来一共有M行,每行有三个整数x(1<=x<=N)、y(1<=y<=N),表示GBQC国有一条由城市x进入通向城市y的单向道路。

Output

对于每组测试数据,用一行输出一个整数表示最少需要设置几个路障。如果没办法从城市1出发走到城市N,则输出“-1”(不包括引号)。

Sample Input

3 41 11 21 31 33 21 33 22 0

Sample Output

30-1

Hint

​ 由于数据量较大,推荐使用scanf和printf。

思路:这个题可以这样考虑,最小的路障就可以视为是一个权值的问题,而Dijkstra算法又不会重复走某个点,则每条边的权值就为起始点的出度-1,故先读入图,第一遍记录每个点的出度,第二遍利用第一遍得到的出度建图,跑一边Dijkstra,判断dis[n]是有还是无按要求输出。
我用了紫书的模板

#include <bits/stdc++.h>#define N 101000#define INF 0x3f3f3f3f#define LL long long#define mem(a,n) memset(a,n,sizeof(a))#define fread freopen("in.txt","r",stdin)#define fwrite freopen("out.txt","w",stdout)using namespace std;struct Edge{    int from,to,dist;    Edge(int u,int v,int d):from(u),to(v),dist(d){};};struct HeapNode{    int d,u;    bool operator<(const HeapNode &a) const {        return d>a.d;    }};struct Dijkstra{    int n,m;    vector<Edge> edges;    vector<int> G[N];    bool vis[N];//是否永久标号     int d[N];//松弛操作     int p[N];//最短路中的上一条弧    void init(int n) {        this->n=n;        for(int i=0;i<n;++i){            G[i].clear();        }        edges.clear();    }    void AddEdge(int from,int to,int dist){        edges.push_back(Edge(from,to,dist));        m=edges.size();        G[from].push_back(m-1);    }    void dijkstra(int s){        priority_queue<HeapNode> q;        for(int i=0;i<n;++i){            d[i]=INF;        }        d[s]=0;        mem(vis,0);        q.push((HeapNode){0,s});        while(!q.empty()){            HeapNode x=q.top();            q.pop();            int u=x.u;            if(vis[u]){                continue;            }            vis[u]=true;            for(int i=0;i<G[u].size();++i){                Edge &e=edges[G[u][i]];                if(d[e.to]>d[u]+e.dist){                    d[e.to]=d[u]+e.dist;                    p[e.to]=G[u][i];                    q.push((HeapNode){d[e.to],e.to});                }            }        }    }};int outdeg[N],path[N][2];Dijkstra Dick;int main(){    ios::sync_with_stdio(false);    int n,d,c1,c2,cnt;    while(cin>>n>>d){        Dick.init(n+1);        mem(outdeg,0);        for(int i=0;i<d;++i){            cin>>path[i][0]>>path[i][1];            ++outdeg[path[i][0]];        }        for(int i=0;i<d;++i){            Dick.AddEdge(path[i][0],path[i][1],outdeg[path[i][0]]-1);        }        Dick.dijkstra(1);        cout<<(Dick.d[n]==INF?-1:Dick.d[n])<<endl;     }    return 0;}
原创粉丝点击