zoukankan      html  css  js  c++  java
  • codeforces 567 E. President and Roads 【 最短路 桥 】

    给出一个有向图,从起点走到终点(必须走最短路),问一条边是否一定会被经过,如果不经过它,可以减小它的多少边权使得经过它(边权不能减少到0)

    正反向建图,分别求出起点到每个点的最短距离,终点到每个点的最短距离(用这个可以算出减小的边权)

    再将在最短路径上的边重新建图。求出里面的桥,就是必须经过的边

    wa了一上午------呜呜呜呜

    先wa 19  是因为求桥的时候是无向图,数组开小了一半

    然后 wa 46 ,是因为dis[]数组初始化为 1 << 30 -1 ,应该再开大点 ,开成 1 << 50 -1

    我写成 1 LL * 50 -----一直wa 19------

    5555555555555555555--------sad-------

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <vector>
      6 #include <map>
      7 #include <set>
      8 #include <stack>
      9 #include <queue>
     10 #include <iostream>
     11 #include <algorithm>
     12 using namespace std;
     13 #define lp (p << 1)
     14 #define rp (p << 1|1)
     15 #define getmid(l,r) (l + (r - l) / 2)
     16 #define MP(a,b) make_pair(a,b)
     17 typedef long long ll;
     18 typedef unsigned long long ull;
     19 typedef pair<int,int> pii;
     20 const int INF = (1 << 30) - 1;
     21 const int maxn = 100055;
     22 
     23 int N,M;
     24 ll path;
     25 int first1[maxn],nxt1[10 * maxn],ecnt1;
     26 int first2[maxn],nxt2[10 *maxn],ecnt2;
     27 int first[maxn],nxt[10*maxn],ecnt;
     28 ll dis1[maxn],dis2[maxn];
     29 
     30 int bg[20*maxn],vis[20*maxn],low[maxn],dfn[maxn];
     31 int ans[20*maxn],res[maxn];
     32 int tot,num;
     33 
     34 struct edge{
     35     int v,u,cost;
     36     int tag;
     37     int ge;
     38     int id;
     39     friend bool operator < (edge a,edge b){
     40         return a.cost > b.cost;
     41     }
     42 };
     43 
     44 edge e1[5*maxn],e2[5*maxn],e[5*maxn];
     45 
     46 void init(){
     47     ecnt1 = ecnt2 = ecnt = 0;
     48     memset(first1,-1,sizeof(first1));
     49     memset(first2,-1,sizeof(first2));
     50     memset(first,-1,sizeof(first));
     51 }
     52 
     53 void Add_edge1(int u,int v,int c){
     54     nxt1[++ecnt1] = first1[u];
     55     e1[ecnt1].u = u;
     56     e1[ecnt1].v = v;
     57     e1[ecnt1].cost = c;
     58     e1[ecnt1].tag = 0;
     59     e1[ecnt1].ge = 0;
     60     first1[u] = ecnt1;
     61 }
     62 
     63 void Add_edge2(int u,int v,int c){
     64     nxt2[++ecnt2] = first2[u];
     65     e2[ecnt2].v = v;
     66     e2[ecnt2].cost = c;
     67     e2[ecnt2].tag = 0;
     68     e2[ecnt2].ge = 0;
     69     first2[u] = ecnt2;
     70 }
     71 
     72 void Add_edge(int u,int v,int c){
     73     nxt[ecnt] = first[u];
     74     e[ecnt].v = v;
     75     e[ecnt].u = u;
     76     e[ecnt].id = c;
     77     first[u] = ecnt++;
     78     
     79     nxt[ecnt] = first[v];
     80     e[ecnt].v = u;
     81     e[ecnt].u = v;
     82     e[ecnt].id = c;
     83     first[v] = ecnt++;
     84 }
     85 
     86 struct cmp{
     87     bool operator ()(pii a,pii b){
     88         return a.first > b.first;
     89     }
     90 };
     91 
     92 void Dijstra1(int s){
     93     priority_queue<pii,vector<pii >,cmp> PQ;
     94     dis1[s] = 0;
     95     PQ.push(MP(dis1[s],s));
     96     int cnt = 0;
     97     while(!PQ.empty()){
     98         pii x = PQ.top(); PQ.pop();
     99         if(dis1[x.second] < x.first) continue; 
    100         for(int i = first1[x.second]; i != -1; i = nxt1[i]){
    101             int v = e1[i].v;
    102             if(dis1[v] > dis1[x.second] + e1[i].cost){
    103                 dis1[v] = dis1[x.second] + e1[i].cost;
    104                 PQ.push(MP(dis1[v],v));
    105             }
    106         }
    107     }
    108 }
    109 
    110 void Dijstra2(int s){
    111     priority_queue<pii,vector<pii >,cmp> PQ;
    112     dis2[s] = 0;
    113     PQ.push(MP(dis2[s],s));
    114     int cnt = 0;
    115     while(!PQ.empty()){
    116         pii x = PQ.top(); PQ.pop();
    117         if(dis2[x.second] < x.first) continue; 
    118         for(int i = first2[x.second]; i != -1; i = nxt2[i]){
    119             int v = e2[i].v;
    120             if(dis2[v] > dis2[x.second] + e2[i].cost){
    121                 dis2[v] = dis2[x.second] + e2[i].cost;
    122                 PQ.push(MP(dis2[v],v));
    123             }
    124         }
    125     }
    126 }
    127 
    128 
    129 void Dfs(int p,int pre){
    130     dfn[p] = low[p] = ++tot;
    131     for(int i = first[p]; ~i; i = nxt[i]){
    132         int v = e[i].v;
    133         if(vis[i]) continue;
    134         vis[i] = vis[i ^ 1] = true;
    135         if(!dfn[v]){
    136             Dfs(v,p);
    137             low[p] = min(low[p],low[v]);
    138             if(low[v] > dfn[p]) {
    139                 bg[i] = bg[i ^ 1] = true;
    140                 ans[e[i].id] = 1;
    141             }
    142         }
    143         else low[p] = min(low[p],dfn[v]);
    144     }
    145 }
    146 
    147 void Tarjan(){
    148     memset(dfn,0,sizeof(dfn));
    149     memset(low,0,sizeof(low));
    150     memset(bg,false,sizeof(bg));
    151     memset(vis,false,sizeof(vis));
    152     tot = 0;
    153     for(int i = 1; i <= N; ++i) if( dfn[i] == 0) Dfs(i,-1);
    154 }
    155 
    156 void solve(){
    157     memset(res,-1,sizeof(res));
    158     for(int i = 1;i <= M;i++){
    159         int u = e1[i].u;
    160         int v = e1[i].v;
    161         if(ans[i] == 1) {
    162             res[i] = 0;
    163             continue;
    164         }
    165         ll need = path - dis1[u] - dis2[v];
    166         if(need > 1){
    167              res[i] = e1[i].cost - need + 1;
    168         }
    169     }
    170     
    171     
    172     for(int i = 1;i <= M;i++){
    173         if(res[i] == 0) puts("YES");
    174         else if(res[i] == -1) puts("NO");
    175         else printf("CAN %d
    ",res[i]);
    176     }
    177 }
    178 
    179 int main(){
    180     int a,b,c,s,t;
    181     num = 0;
    182     while(scanf("%d%d%d%d",&N,&M,&s,&t) != EOF){
    183         num++;
    184         init();
    185         int x;
    186         
    187         for(int i = 1; i <= M; ++i){
    188             scanf("%d%d%d",&a,&b,&c);
    189             Add_edge1(a,b,c);
    190             Add_edge2(b,a,c);
    191         }
    192         
    193         for(int i = 1;i <= N;i++) dis1[i] = dis2[i] = 1ll << 50;
    194         
    195         Dijstra1(s);
    196         Dijstra2(t);
    197         path = dis1[t];
    198        
    199         for(int u = 1;u <= N;u++){
    200             for(int i = first1[u];~i;i = nxt1[i]){
    201                 int v = e1[i].v;
    202                 if(dis1[u] + dis2[v] + e1[i].cost == path) {
    203                     e1[i].tag = 1;
    204                     e2[i].tag = 1;
    205                     Add_edge(u,v,i);
    206                 }
    207             }
    208         }
    209         
    210         memset(ans,0,sizeof(ans));
    211         Tarjan();        
    212         solve();
    213     }
    214     return 0;
    215 }
    View Code
  • 相关阅读:
    [排错] VO对象和POJO对象的关系
    celery(异步处理)+redis
    django开发经验(每日生鲜)
    开发流程
    linux 使用问题
    磁盘的操作
    文件系统的简单操作
    LINUX磁盘与档案系统
    文件操作
    Linux文档修改
  • 原文地址:https://www.cnblogs.com/wuyuewoniu/p/4720474.html
Copyright © 2011-2022 走看看