标签:
给出一个有向图,从起点走到终点(必须走最短路),问一条边是否一定会被经过,如果不经过它,可以减小它的多少边权使得经过它(边权不能减少到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\n",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 }
codeforces 567 E. President and Roads 【 最短路 桥 】
标签:
原文地址:http://www.cnblogs.com/wuyuewoniu/p/4720474.html