【在期末考试复习的间隙做题真的很不容易啊qaq
【下周就要期末考试了,祝我能考个好成绩ovo
sb题,先跑一遍最短路预处理,然后按照题目加边跑最大流就没了。注意答案要用long long存储。
跟BZOJ 1266有点像呀。
注意结点容量的处理方法:对于每个点s,设它的结点容量为c。把s拆成两个点s1和s2,从s1往s2连一条容量为c的边;对于终点为s的边,其终点为s1;对于起点为s的边,其起点为s2。
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 7 const size_t Max_N(1050); 8 const size_t Max_M(600050); 9 const long long int INF(0X7F7F7F7F7F7F7F7FLL); 10 11 void Get_Val(int &Ret) 12 { 13 Ret = 0; 14 char ch; 15 while ((ch = getchar()), (ch > '9' || ch < '0')) 16 ; 17 do 18 { 19 (Ret *= 10) += ch - '0'; 20 } 21 while ((ch = getchar()), (ch >= '0' && ch <= '9')); 22 } 23 24 int N; 25 int G[Max_N][Max_N]; 26 27 int total; 28 int head[Max_N]; 29 int to[Max_M], next[Max_M], weight[Max_M]; 30 31 void add_edge(const int &s, const int &t, const int &w) 32 { 33 ++total; 34 to[total] = t, weight[total] = w; 35 next[total] = head[s], head[s] = total; 36 } 37 38 struct Flow_Graph 39 { 40 Flow_Graph() : V(0), Total(0) 41 { 42 memset(Head, 0, sizeof(Head)); 43 memset(To, 0, sizeof(To)), memset(Next, 0, sizeof(Next)); 44 memset(Cap, 0, sizeof(Cap)), memset(Flow, 0, sizeof(Flow)); 45 } 46 int V; 47 int Total; 48 int Head[Max_N], Cur[Max_N]; 49 int To[Max_M], Next[Max_M]; 50 long long int Cap[Max_M], Flow[Max_M]; 51 int Dist[Max_N]; 52 int S, T; 53 54 inline 55 void Add_Edge(const int &tot, const int &s, const int &t, const long long int &c) 56 { 57 To[tot] = t; 58 Next[tot] = Head[s], Head[s] = tot; 59 Cap[tot] = c, Flow[tot] = 0; 60 } 61 inline 62 void Add_Link(const int &s, const int &t, const long long int &c) 63 { 64 Total += 2; 65 Add_Edge(Total, s, t, c); 66 Add_Edge(Total ^ 1, t, s, 0); 67 } 68 69 bool BFS(); 70 long long int DFS(const int&, long long int); 71 long long int Dinic(); 72 }; 73 Flow_Graph MFG; 74 75 void init() 76 { 77 int M, a, b, d; 78 Get_Val(N), Get_Val(M); 79 memset(G, 0X3F, sizeof(G)); 80 for (int i = 1;i <= N;++i) 81 G[i][i] = 0; 82 while (M--) 83 { 84 Get_Val(a), Get_Val(b), Get_Val(d); 85 G[a][b] = G[b][a] = min(G[a][b], d); 86 add_edge(a, b, d), add_edge(b, a, d); 87 } 88 } 89 90 void Floyd() 91 { 92 for (int k = 1;k <= N;++k) 93 for (int i = 1;i <= N;++i) 94 for (int j = 1;j <= N;++j) 95 G[i][j] = min(G[i][j], G[i][k] + G[k][j]); 96 } 97 98 void make_graph() 99 { 100 Floyd(); 101 int s, t, c; 102 MFG.V = (N << 1), MFG.S = 1, MFG.T = (N << 1); 103 for (s = 1;s <= N;++s) 104 for (int i = head[s];i;i = next[i]) 105 { 106 t = to[i]; 107 if (G[1][N] == G[1][s] + weight[i] + G[t][N]) 108 MFG.Add_Link(s + N, t, INF); 109 } 110 for (int i = 1;i <= N;++i) 111 { 112 Get_Val(c); 113 if (i != 1 && i != N) 114 MFG.Add_Link(i, i + N, c); 115 else 116 MFG.Add_Link(i, i + N, INF); 117 } 118 } 119 120 bool Flow_Graph::BFS() 121 { 122 memset(Dist, 0, sizeof(Dist)); 123 queue<int> Q; 124 Dist[S] = 1, Q.push(S); 125 int Top; 126 while (Q.size()) 127 { 128 Top = Q.front(), Q.pop(); 129 for (int i = Head[Top];i;i = Next[i]) 130 if (!Dist[To[i]] && Cap[i] > Flow[i]) 131 { 132 Dist[To[i]] = Dist[Top] + 1; 133 Q.push(To[i]); 134 } 135 } 136 return Dist[T]; 137 138 } 139 140 long long int Flow_Graph::DFS(const int &u, long long int a) 141 { 142 if (u == T || a == 0LL) 143 return a; 144 long long int Ans(0LL), f; 145 for (int &i = Cur[u];i;i = Next[i]) 146 if (Dist[To[i]] == Dist[u] + 1) 147 if ((f = DFS(To[i], min(a, Cap[i] - Flow[i]))) > 0) 148 { 149 Flow[i] += f; 150 Flow[i ^ 1] -= f; 151 Ans += f; 152 a -= f; 153 if (a == 0LL) 154 break; 155 } 156 return Ans; 157 } 158 159 long long int Flow_Graph::Dinic() 160 { 161 long long int Ans(0LL); 162 while (BFS()) 163 { 164 for (int i = 1;i <= V;++i) 165 Cur[i] = Head[i]; 166 Ans += DFS(S, INF); 167 } 168 return Ans; 169 } 170 171 int main() 172 { 173 init(); 174 make_graph(); 175 printf("%lld", MFG.Dinic()); 176 return 0; 177 }