标签:
先对原图求一遍最短路。。这里用什么算法都行,毕竟N很小直接floyd就可以啦。。
然后把可以当做最短路上的边加入到一个新图当中去。。求一遍最小割(最大流)就好啦。。
可以当做最短路的的边的条件:G[1][u]+time+G[v][N]=G[1][N]
然而这题我WA了三次。。因为没有在跑完最短路后重新建图,而是直接在Dinic用BFS构造残余网络分层图的时候判断条件G[1][u]+time+G[v][N]=G[1][N]。。这会导致有可能无法反向增广。。QAQ我毕竟还是too simple需要提高自己的姿势水平
1 #include <queue> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 7 using namespace std; 8 9 const size_t Max_N(505); 10 const size_t Max_M(600050); 11 const int INF(0X7F7F7F7F); 12 13 void Get_Val(unsigned int &ret) 14 { 15 ret = 0; 16 char ch; 17 while ((ch = getchar()), (ch > ‘9‘ || ch < ‘0‘)) 18 ; 19 do 20 { 21 (ret *= 10) += ch - ‘0‘; 22 } 23 while ((ch = getchar()), (ch >= ‘0‘ && ch <= ‘9‘)); 24 } 25 26 void Get_Val(int &ret) 27 { 28 ret = 0; 29 char ch; 30 while ((ch = getchar()), (ch > ‘9‘ || ch < ‘0‘)) 31 ; 32 do 33 { 34 (ret *= 10) += ch - ‘0‘; 35 } 36 while ((ch = getchar()), (ch >= ‘0‘ && ch <= ‘9‘)); 37 } 38 39 struct edge 40 { 41 edge(const size_t &a = 0, const int &b = 0, const int &c = 0) : To(a), Time(b), Cost(c) {} 42 size_t To; 43 int Time, Cost; 44 }; 45 46 size_t N; 47 int G[Max_N][Max_N]; 48 vector<edge> Adj[Max_N]; 49 50 unsigned int Total; 51 unsigned int Head[Max_N]; 52 unsigned int To[Max_M], Next[Max_M]; 53 int Cap[Max_M], Flow[Max_M]; 54 55 inline 56 void Add_Edge(const size_t &tot, const size_t &s, const size_t &t, const int &c) 57 { 58 To[tot] = t; 59 Next[tot] = Head[s], Head[s] = tot; 60 Cap[tot] = c, Flow[tot] = 0; 61 } 62 63 void init() 64 { 65 unsigned int M; 66 size_t u, v; 67 int t, c; 68 Get_Val(N); 69 Get_Val(M); 70 memset(G, 0X3F, sizeof(G)); 71 for (size_t i = 1;i <= N;++i) 72 G[i][i] = 0; 73 while (M--) 74 { 75 Get_Val(u); 76 Get_Val(v); 77 Get_Val(t); 78 Get_Val(c); 79 G[u][v] = G[v][u] = t; 80 Adj[u].push_back(edge(v, t, c)); 81 Adj[v].push_back(edge(u, t, c)); 82 } 83 } 84 85 void Floyd() 86 { 87 for (size_t k = 1;k <= N;++k) 88 for (size_t i = 1;i <= N;++i) 89 for (size_t j = 1;j <= N;++j) 90 G[i][j] = min(G[i][j], G[i][k] + G[k][j]); 91 for (size_t u = 1;u <= N;++u) 92 for (size_t i = 0;i != Adj[u].size();++i) 93 if (G[1][u] + Adj[u][i].Time + G[Adj[u][i].To][N] == G[1][N]) 94 { 95 Total += 2; 96 Add_Edge(Total, u, Adj[u][i].To, Adj[u][i].Cost); 97 Add_Edge(Total ^ 1, Adj[u][i].To, u, 0); 98 } 99 100 } 101 102 unsigned int Dist[Max_N]; 103 size_t Cur[Max_N]; 104 bool BFS(const size_t &S, const size_t &T) 105 { 106 memset(Dist, 0, sizeof(Dist)); 107 queue<size_t> Q; 108 Q.push(S); 109 Dist[S] = 1; 110 size_t Top; 111 112 while (Q.size()) 113 { 114 Top = Q.front(); 115 Q.pop(); 116 for (size_t i = Head[Top];i;i = Next[i]) 117 if (!Dist[To[i]] && Cap[i] > Flow[i]) 118 { 119 Dist[To[i]] = Dist[Top] + 1; 120 Q.push(To[i]); 121 } 122 } 123 124 return Dist[T]; 125 } 126 127 int DFS(const size_t &u, int a, const size_t &T) 128 { 129 if (u == T || a == 0) 130 return a; 131 int Ans(0), f; 132 for (size_t &i = Cur[u];i;i = Next[i]) 133 if (Dist[To[i]] == Dist[u] + 1) 134 if (((f = DFS(To[i], min(a, Cap[i] - Flow[i]), T))) > 0) 135 { 136 Ans += f; 137 a -= f; 138 Flow[i] += f; 139 Flow[i ^ 1] -= f; 140 if (a == 0) 141 break; 142 } 143 return Ans; 144 } 145 146 int Dinic(const size_t &S, const size_t &T) 147 { 148 int Ans(0); 149 while (BFS(S, T)) 150 { 151 for (size_t i = 1;i <= N;++i) 152 Cur[i] = Head[i]; 153 Ans += DFS(S, INF, T); 154 } 155 return Ans; 156 } 157 158 int main() 159 { 160 init(); 161 162 Floyd(); 163 164 printf("%d\n%d", G[1][N], Dinic(1, N)); 165 166 return 0; 167 }
标签:
原文地址:http://www.cnblogs.com/Created-equal/p/5052276.html