【HDOJ】3416 Marriage Match IV
先求SPSS。然后遍历每条边,检查是否为最短路径的边,如果是(dis[v]==dis[u]+w)则加入到网络流中。最后Dinic最大流.
1 /* 3416 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 const int INF = 0x1f1f1f1f; 43 const int maxn = 1005; 44 const int maxe = 200005; 45 int head[maxn], nxt[maxe], V[maxe], F[maxe]; 46 int head_[maxn], nxt_[maxe], V_[maxe], W[maxe]; 47 int dis[maxn], pre[maxn], ID[maxn]; 48 bool visit[maxn]; 49 int n, m; 50 51 void addEdge_(int u, int v, int w) { 52 V_[m] = v; 53 W[m] = w; 54 nxt_[m] = head_[u]; 55 head_[u] = m++; 56 } 57 58 void addEdge(int u, int v, int c) { 59 V[m] = v; 60 F[m] = c; 61 nxt[m] = head[u]; 62 head[u] = m++; 63 64 V[m] = u; 65 F[m] = 0; 66 nxt[m] = head[v]; 67 head[v] = m++; 68 } 69 70 void spfa(int u) { 71 int v, k; 72 queue<int> Q; 73 74 memset(dis, 0x1f, sizeof(dis)); 75 memset(visit, false, sizeof(visit)); 76 Q.push(u); 77 dis[u] = 0; 78 visit[u] = true; 79 80 while (!Q.empty()) { 81 u = Q.front(); 82 Q.pop(); 83 visit[u] = false; 84 for (k=head_[u]; k!=-1; k=nxt_[k]) { 85 v = V_[k]; 86 if (dis[v] > dis[u]+W[k]) { 87 dis[v] = dis[u] + W[k]; 88 if (!visit[v]) { 89 visit[v] = true; 90 Q.push(v); 91 } 92 } 93 } 94 } 95 } 96 97 bool bfs(int s, int t) { 98 queue<int> Q; 99 int u, v, k; 100 101 memset(dis, 0, sizeof(dis)); 102 Q.push(s); 103 dis[s] = 1; 104 pre[s] = s; 105 106 while (!Q.empty()) { 107 u = Q.front(); 108 Q.pop(); 109 for (k=head[u]; k!=-1; k=nxt[k]) { 110 v = V[k]; 111 if (F[k] && !dis[v]) { 112 dis[v] = dis[u] + 1; 113 pre[v] = u; 114 ID[v] = k; 115 Q.push(v); 116 } 117 } 118 } 119 120 return dis[t] == 0; 121 } 122 123 int dfs(int u, int t, int val) { 124 if (u==t || val==0) 125 return val; 126 127 int ret = 0, tmp; 128 int v, k; 129 130 for (k=head[u]; k!=-1; k=nxt[k]) { 131 v = V[k]; 132 if (dis[v]==dis[u]+1 && F[k] && (tmp=dfs(v, t, min(val, F[k])))>0) { 133 F[k] -= tmp; 134 F[k^1] += tmp; 135 ret += tmp; 136 val -= tmp; 137 if (val == 0) 138 break; 139 } 140 } 141 142 return ret; 143 } 144 145 int Dinic(int s, int t) { 146 int ret = 0, tmp; 147 148 while (1) { 149 if (bfs(s, t)) 150 break; 151 152 tmp = dfs(s, t, INF); 153 ret += tmp; 154 } 155 156 return ret; 157 } 158 159 int main() { 160 ios::sync_with_stdio(false); 161 #ifndef ONLINE_JUDGE 162 freopen("data.in", "r", stdin); 163 freopen("data.out", "w", stdout); 164 #endif 165 166 int tt; 167 int s, t, n_, m_; 168 int u, v, k, w; 169 int ans; 170 171 scanf("%d", &tt); 172 while (tt--) { 173 scanf("%d %d", &n_, &m_); 174 memset(head_, -1, sizeof(head_)); 175 m = 0; 176 while (m_--) { 177 scanf("%d %d %d", &u, &v, &w); 178 if (u != v) 179 addEdge_(u, v, w); 180 } 181 182 scanf("%d %d", &s, &t); 183 spfa(s); 184 185 m = 0; 186 memset(head, -1, sizeof(head)); 187 rep(i, 1, n_+1) { 188 for (k=head_[i]; k!=-1; k=nxt_[k]) { 189 v = V_[k]; 190 if (dis[v] == dis[i] + W[k]) { 191 addEdge(i, v, 1); 192 } 193 } 194 } 195 196 ans = Dinic(s, t); 197 printf("%d\n", ans); 198 } 199 200 #ifndef ONLINE_JUDGE 201 printf("time = %d.\n", (int)clock()); 202 #endif 203 204 return 0; 205 }