zoukankan      html  css  js  c++  java
  • SGU 515 Dij+Topsort

    题目大意:给定N个点M条边的无向图,以及一些必经过的点,求输出长度最短路径。

    题目分析:想办法把图转化成DAG,于是找出最远点建立最短路树,跑topsort

      1 #include<bits/stdc++.h>
      2 #define maxn 100010
      3 #define LL long long
      4 #define Pii pair<LL,int>
      5 #define pb push_back
      6 #define mp make_pair
      7 #define fi first
      8 #define se second
      9 const LL INF = 0x7fffffff;
     10 using namespace std;
     11 LL d[maxn], mi = -1;
     12 struct Node{
     13     int u,v;
     14     LL cost;
     15 }e[maxn];
     16 int n, m, dir, ddir, cnt = 0, dp[maxn];
     17 LL cc[maxn];
     18 bool cover[maxn];
     19 int seg[maxn], k;
     20 vector<Pii> G[maxn];
     21 vector<pair<LL, pair<int,int> > > T[maxn];
     22 int in[maxn];
     23 int pre[maxn];
     24 int path[maxn], num = 0;
     25 void find(int x){
     26     if(x == dir) return;
     27     int current_path = pre[x];
     28     if(e[current_path].u == x)
     29         find(e[current_path].v);    
     30     else     
     31         find(e[current_path].u);
     32     path[++ num] = current_path;
     33 }
     34 void Dij(int fa){
     35     bool vis[maxn];
     36     memset(vis, false, sizeof(vis));
     37     for(int i = 1; i <= n; i ++){
     38         d[i] = INF;
     39     }
     40     d[fa] = 0;
     41     priority_queue<Pii,vector<Pii>, greater<Pii> > Q;
     42     Q.push(mp(d[fa], fa));
     43     Pii p, cur;
     44     int pos, now;
     45     while(!Q.empty()){
     46         p = Q.top();
     47         pos = p.se;
     48         Q.pop();
     49         if(vis[pos]) continue;
     50         vis[pos] = true;
     51         for(int i = 0; i < G[pos].size(); i ++){
     52             cur = G[pos][i];
     53             if(!vis[cur.se] && d[cur.se] > d[pos] + cur.fi){
     54                 d[cur.se] = d[pos] + cur.fi;
     55                 Q.push(mp(d[cur.se], cur.se));
     56             }
     57         }
     58     }
     59 }
     60 int main(){
     61     int a, b, t;
     62     cin >> n >> m;
     63     for(int i = 1; i <= m; i ++){
     64         cin >> a >> b >> t;
     65         if(a == b){
     66             m --;
     67             i --;
     68             continue;
     69         }
     70         e[++ cnt].u = a, e[cnt].v = b, e[cnt].cost = t; 
     71         G[a].pb(mp(t, b));
     72         G[b].pb(mp(t, a));
     73     }
     74     cin >> k;
     75     for(int i = 1; i <= k; i ++){
     76         cin >> seg[i];
     77         cover[seg[i]] = true;
     78     }
     79     Dij(seg[1]);
     80     for(int i = 1; i <= n; i ++){
     81         if(cover[i] && d[i] > mi){
     82             mi = d[i];
     83             dir = i;
     84         }
     85     }
     86     Dij(dir);
     87     for(int i = 1; i <= cnt; i ++){
     88         if(e[i].u == e[i].v) continue;
     89         if(d[e[i].u] == d[e[i].v] + e[i].cost){
     90             T[e[i].v].pb(mp(e[i].cost, mp(e[i].u, i)));
     91             in[e[i].u] ++;
     92         }
     93         else if(d[e[i].v] == d[e[i].u] + e[i].cost){
     94             T[e[i].u].pb(mp(e[i].cost, mp(e[i].v, i)));
     95             in[e[i].v] ++;
     96         }
     97     }
     98     queue<int> Q;
     99     for(int i = 1; i <= n; i ++){
    100         dp[i] = (cover[i] ? 1 : 0);
    101         if(in[i] == 0) Q.push(i);
    102     }
    103     int now, p, delta;
    104     while(!Q.empty()){
    105         p = Q.front();
    106         Q.pop();
    107         for(int i = 0; i < T[p].size(); i ++){
    108             now = T[p][i].se.fi;
    109             delta = (cover[now] ? 1 : 0);
    110             if(dp[now] < dp[p] + delta){
    111                 dp[now] = dp[p] + delta;
    112                 cc[now] = cc[p] + T[p][i].fi;
    113                 pre[now] = T[p][i].se.se; 
    114             }
    115             else if(dp[now] == dp[p] + delta){
    116                 if(cc[now] > cc[p] + T[p][i].fi){
    117                     cc[now] = cc[p] + T[p][i].fi;
    118                     pre[now] = T[p][i].se.se;
    119                 }
    120             }
    121             in[now] --;
    122             if(in[now] == 0){
    123                 Q.push(now);
    124             }
    125         }
    126     }
    127     int mmi = 0;
    128     LL ccc = INF;
    129     for(int i = 1; i <= n; i ++){
    130         if(mmi < dp[i]){
    131             mmi = dp[i];
    132             ccc = cc[i];
    133             ddir = i;
    134         }
    135         else if(mi == dp[i]){
    136             if(cc[i] < ccc){
    137                 cc[i] = ccc;
    138                 ddir = i;
    139             }
    140         }
    141     }
    142     find(ddir);
    143     cout << num << endl;
    144     for(int i = 1; i <= num; i ++){
    145         cout << path[i] << ' ';
    146     }
    147     return 0;
    148 }
  • 相关阅读:
    Understand Rails Authenticity Token
    正则表达式:数值及数值型字符串三位一组格式化
    ceph主要数据结构解析2-Rados.h文件
    遍历聚合对象中的元素——迭代器模式(三)
    ceph主要数据结构解析3-Ceph_fs.h文件
    linux crontab 定时命令
    mysql数据类型详解
    遍历聚合对象中的元素——迭代器模式(四)
    Eclipse自动插件依赖的一种配置解决方式
    php缓存小技巧
  • 原文地址:https://www.cnblogs.com/poler/p/7688898.html
Copyright © 2011-2022 走看看