hdu 3376 Matrix Again
对时间复杂度要求还挺高的#include<cstdio> #include<algorithm> #include<vector> #include<cmath> #include<set> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int MAXN = 360000*2+10, inf = 0x3f3f3f3f; int n, m; struct _node { int to, next, cost, val; _node(int a, int b, int c, int d): to(a),next(b),cost(c),val(d) {} _node() {} }ee[MAXN*10]; int head[MAXN], cnt, ppre[MAXN], wt[MAXN]; inline void add(int u, int v, int cost, int val) { ee[cnt] = _node(v, head[u], cost, val); head[u] = cnt++; ee[cnt] = _node(u, head[v], -cost, 0); head[v] = cnt++; } int q[MAXN*10], vis[MAXN], dis[MAXN], fa[MAXN], pos[MAXN]; int spfa(int s, int t) { int bg = 0, ed = 0; for (int i = 0; i<= t+10; ++i) { vis[i] = 0; fa[i] = -1; dis[i] = inf; } dis[s] = 0; q[ed++] = s; while (bg < ed) { int u = q[bg++]; vis[u] = 0; for (int i = head[u]; ~i; i=ee[i].next) { int v = ee[i].to; if (ee[i].val > 0 && dis[v]>dis[u]+ee[i].cost) { dis[v]=dis[u]+ee[i].cost; fa[v] = u; pos[v] = i; if (!vis[v]) { vis[v] = 1; q[ed++] = v; } } } } return fa[t] != -1; } int minCost_maxFlow(int s, int t) { int res = 0; while (spfa(s, t)) { for (int i = t; i!=s; i=fa[i]) { --ee[pos[i]].val; ++ee[pos[i]^1].val; } res += dis[t]; } return res; } int mmp[605][605]; void minit() { cnt = 0; memset(head, -1, sizeof head); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif int s, t, N; while (scanf("%d", &n) != EOF) { N = n*n; minit(); for (int i = 0; i< n; ++i) { for (int j = 0; j< n; ++j) { scanf("%d", &mmp[i][j]); } } s = 0 ; t = 2*N-1; for (int i = 0, p; i< n; ++i) { for (int j = 0; j< n; ++j) { p = i*n+j; if (i+1 < n) add(p+N, p+n, 0, 1); if (j+1 < n) add(p+N, p+1, 0, 1); if (p == 0 || p == N-1) {add(p, p+N, 0, 2);} else add(p, p+N, -mmp[i][j], 1); } } printf("%d\n", -minCost_maxFlow(s, t)+mmp[0][0]+mmp[n-1][n-1]); } return 0; }
hdu 4411 Arrest
为了保障每个点必被访问一次,需要将一个点拆分后连一条费用极小的边#include<cstdio> #include<algorithm> #include<vector> #include<cmath> #include<set> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int MAXN = 105*2, inf = 0x3f3f3f3f; int n, m, k; struct _node { int to, next, cost, val; _node(int a, int b, int c, int d): to(a),next(b),cost(c),val(d) {} _node() {} }ee[MAXN*MAXN]; int head[MAXN], cnt; void add(int u, int v, int cost, int val) { ee[cnt] = _node(v, head[u], cost, val); head[u] = cnt++; ee[cnt] = _node(u, head[v], -cost, 0); head[v] = cnt++; } int q[MAXN*MAXN], vis[MAXN], dis[MAXN], fa[MAXN], pos[MAXN]; int spfa(int s, int t) { int bg = 0, ed = 0; memset(vis, 0, sizeof vis); memset(fa, -1, sizeof fa); memset(dis, 0x3f, sizeof dis); dis[s] = 0; q[ed++] = s; while (bg < ed) { int u = q[bg++]; vis[u] = 0; for (int i = head[u]; ~i; i=ee[i].next) { int v = ee[i].to; if (ee[i].val > 0 && dis[v]>dis[u]+ee[i].cost) { dis[v]=dis[u]+ee[i].cost; fa[v] = u; pos[v] = i; if (!vis[v]) { vis[v] = 1; q[ed++] = v; } } } } return fa[t] != -1; } int minCost_maxFlow(int s, int t) { int flow = 0; int res = 0; while (spfa(s, t)) { int mn = inf; for (int i = t; i!= s; i = fa[i]) { if (mn > ee[pos[i]].val) mn = ee[pos[i]].val; } for (int i = t; i!=s; i=fa[i]) { ee[pos[i]].val -= mn; ee[pos[i]^1].val += mn; } flow += mn; res += dis[t]*mn; } return res; } void init() { cnt = 0; memset(head, -1, sizeof head); } int gg[MAXN/2][MAXN/2]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif while (scanf("%d%d%d", &n, &m, &k) && (n+m+k)) { int u, v, w; memset(gg, inf, sizeof gg); for (int i = 0; i<= n; ++i) gg[i][i] = 0; for (int i = 0; i< m; ++i) { scanf("%d%d%d", &u, &v, &w); if (gg[u][v] > w) gg[u][v] = gg[v][u] = w; } for (int kk = 0; kk<= n; ++kk) for (int i = 0; i<= n; ++i) for (int j = 0; j<= n; ++j) if (gg[i][j] > gg[i][kk] + gg[kk][j]) gg[i][j] = gg[i][kk] + gg[kk][j]; init(); int res = 0, s = 2*n+1, t = 2*n+2; add(s, 0, 0, k); add(0, t, 0, k); for (int i = 1; i<= n; ++i) add(0, i, gg[0][i], 1), add(i, i+n, -1000000, 1), add(i+n, t, gg[i][0], 1); for (int i = 1; i<= n; ++i) for (int j = i+1; j<= n; ++j) add(i+n, j, gg[i][j], 1); printf("%d\n", minCost_maxFlow(s,t)+1000000*n); } return 0; }
hdu 3667 Transportation
将每条边拆分成val = 1 & cost = a, 3a, 5a, 7a ... a(2c-1) 的边#include<stdio.h> #include<queue> using namespace std; const int MAXN = 110, inf = 0x3f3f3f3f; struct _edge { int v, next, val, cost; _edge(){} }e[500010]; int head[MAXN], cnt, fa[MAXN], dis[MAXN], vis[MAXN], pos[MAXN]; int n, m; inline void add(int u, int v, int val, int c) { e[cnt].v = v; e[cnt].val = val, e[cnt].cost = c; e[cnt].next = head[u]; head[u] = cnt++; e[cnt].v = u; e[cnt].val = 0; e[cnt].cost = -c; e[cnt].next = head[v]; head[v] = cnt++; } bool spfa(int s, int t) { for(int i = 0; i<= t; ++i) fa[i]=-1,dis[i]=inf,vis[i]=0; int bg = 0, ed = 0, p; queue<int> q; q.push(s); dis[s] = 0; vis[s] = 1; while (!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; for (int i = head[u]; ~i; i=e[i].next) { int v = e[i].v; if (e[i].val > 0 && dis[v] > (p = dis[u]+e[i].cost)) { dis[v] = p; fa[v] = u; pos[v] = i; if (!vis[v]) { vis[v] = 1; q.push(v); } } } } return fa[t] != -1; } void minCost_maxFlow(int s, int t, int all) { int f = 0; __int64 cost = 0; while (spfa(s,t)) { int mn = 1; for (int i=t; i!=s; i=fa[i]) e[pos[i]].val-=mn, e[pos[i]^1].val+=mn; f += mn; cost += dis[t]; } if (f != all) {printf("-1\n"); return ;} printf("%d\n", cost); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif int k, u, v, a, c; while(~scanf("%d%d%d", &n, &m, &k)) { cnt = 0; memset(head, -1, sizeof head); for (int i = 0; i< m; ++i) { scanf("%d%d%d%d", &u, &v, &a, &c); for (int j = 1; j<= c; ++j) { add(u, v, 1, a*(2*j-1)); } } add(0, 1, k, 0); minCost_maxFlow(0, n, k); } return 0; }