求边不可重复的最短路条数
先从起点到终点用一次dijkstra,再从终点到起点用一次dijkstra,来判断一条边是否在最短路上
如果在,就将这条边的两个端点连起来,容量为1
再跑一下dinic(),最大流就是不可重复的最短路条数
还是想不到怎么建图啊------
每次做网络流的题目---
诶---该怎么建图啊---
想了一会儿----啊--不会啊---
搜一下题解吧---
啊,原来这样连边啊---
啊,原来需要---floyd / 并查集 /dijkstra /------
啊---快,粘一粘模板---
恩--试着跑一发---
诶--怎么不对---
原来数组开小了,,终点没有改过来--
好,厚着脸皮交一发---
哇----居然过了-------------------------------------------------
可是还是不会写网络流
唉--不说了---滚了---
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 #define MP(a,b) make_pair(a,b) 13 using namespace std; 14 15 typedef long long ll; 16 typedef unsigned long long ull; 17 typedef pair<int,int> pii; 18 const int INF = (1 << 30) - 1; 19 const int maxn = 100055; 20 21 int path; 22 int first1[maxn],nxt1[10 * maxn],ecnt1; 23 int first2[maxn],nxt2[10 *maxn],ecnt2; 24 int first[maxn],nxt[10*maxn],ecnt; 25 int dis1[maxn],dis2[maxn]; 26 int st,ed,lev[maxn],now[maxn]; 27 int n,m; 28 29 int vis[20*maxn]; 30 31 struct edge{ 32 int v,u,cost; 33 int c; 34 int next; 35 friend bool operator < (edge a,edge b){ 36 return a.cost > b.cost; 37 } 38 }; 39 40 edge e1[5*maxn],e2[5*maxn],e[5*maxn]; 41 42 void init(){ 43 ecnt1 = ecnt2 = ecnt = 0; 44 memset(first1,-1,sizeof(first1)); 45 memset(first2,-1,sizeof(first2)); 46 memset(first,-1,sizeof(first)); 47 } 48 49 void Add_edge1(int u,int v,int c){ 50 nxt1[++ecnt1] = first1[u]; 51 e1[ecnt1].u = u; 52 e1[ecnt1].v = v; 53 e1[ecnt1].cost = c; 54 first1[u] = ecnt1; 55 } 56 57 void Add_edge2(int u,int v,int c){ 58 nxt2[++ecnt2] = first2[u]; 59 e2[ecnt2].v = v; 60 e2[ecnt2].cost = c; 61 first2[u] = ecnt2; 62 } 63 64 void Add_edge(int u,int v,int c){ 65 e[ecnt].next = first[u]; 66 e[ecnt].v = v; 67 e[ecnt].u = u; 68 e[ecnt].c = c; 69 first[u] = ecnt++; 70 } 71 72 struct cmp{ 73 bool operator ()(pii a,pii b){ 74 return a.first > b.first; 75 } 76 }; 77 78 void Dijstra1(int s){ 79 priority_queue<pii,vector<pii >,cmp> PQ; 80 dis1[s] = 0; 81 PQ.push(MP(dis1[s],s)); 82 int cnt = 0; 83 while(!PQ.empty()){ 84 pii x = PQ.top(); PQ.pop(); 85 if(dis1[x.second] < x.first) continue; 86 for(int i = first1[x.second]; i != -1; i = nxt1[i]){ 87 int v = e1[i].v; 88 if(dis1[v] > dis1[x.second] + e1[i].cost){ 89 dis1[v] = dis1[x.second] + e1[i].cost; 90 PQ.push(MP(dis1[v],v)); 91 } 92 } 93 } 94 } 95 96 void Dijstra2(int s){ 97 priority_queue<pii,vector<pii >,cmp> PQ; 98 dis2[s] = 0; 99 PQ.push(MP(dis2[s],s)); 100 int cnt = 0; 101 while(!PQ.empty()){ 102 pii x = PQ.top(); PQ.pop(); 103 if(dis2[x.second] < x.first) continue; 104 for(int i = first2[x.second]; i != -1; i = nxt2[i]){ 105 int v = e2[i].v; 106 if(dis2[v] > dis2[x.second] + e2[i].cost){ 107 dis2[v] = dis2[x.second] + e2[i].cost; 108 PQ.push(MP(dis2[v],v)); 109 } 110 } 111 } 112 } 113 114 bool bfs(){ 115 queue<int> q; 116 while(!q.empty()) q.pop(); 117 q.push(st); 118 memset(lev,-1,sizeof(lev)); 119 lev[st] = 0; 120 while(!q.empty()){ 121 int x = q.front();q.pop(); 122 for(int i = first[x];~i;i = e[i].next){ 123 int v = e[i].v; 124 if(lev[v] < 0 && e[i].c > 0){ 125 lev[v] = lev[x] + 1; 126 q.push(v); 127 } 128 } 129 } 130 return lev[ed] != -1; 131 } 132 133 int dfs(int p,int minf){ 134 if(p == ed || minf == 0) return minf; 135 for(int &i = now[p];~i;i = e[i].next){ 136 int v = e[i].v; 137 if(lev[v] == lev[p] + 1 && e[i].c > 0){ 138 int d = dfs(v,min(e[i].c,minf)); 139 if(d > 0){ 140 e[i].c -= d; 141 e[i^1].c += d; 142 return d; 143 } 144 } 145 } 146 return 0; 147 } 148 149 int dinic(){ 150 int max_flow = 0,p1; 151 while(bfs()){ 152 memcpy(now,first,sizeof(first)); 153 while((p1 = dfs(st,INF)) > 0) 154 max_flow += p1; 155 } 156 return max_flow; 157 } 158 159 160 161 int main(){ 162 int a,b,c; 163 int T; 164 scanf("%d",&T); 165 while(T--){ 166 scanf("%d %d",&n,&m); 167 init(); 168 for(int i = 1; i <= m; ++i){ 169 scanf("%d%d%d",&a,&b,&c); 170 Add_edge1(a,b,c); 171 Add_edge2(b,a,c); 172 } 173 scanf("%d %d",&st,&ed); 174 175 for(int i = 1;i <= n;i++) dis1[i] = dis2[i] = INF; 176 177 Dijstra1(st); 178 Dijstra2(ed); 179 path = dis1[ed]; 180 181 // for(int i = 1;i <= n;i++) 182 // printf("dis1[%d] = %d dis2[%d] = %d ",i,dis1[i],i,dis2[i]); 183 184 for(int u = 1;u <= n;u++){ 185 for(int i = first1[u];~i;i = nxt1[i]){ 186 int v = e1[i].v; 187 if(dis1[u] + dis2[v] +e1[i].cost == path){ 188 // printf("u = %d v = %d ",u,v); 189 Add_edge(u,v,1); 190 Add_edge(v,u,0); 191 } 192 } 193 } 194 printf("%d ",dinic()); 195 } 196 return 0; 197 }