#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<vector> #include<utility> #include<map> #include<set> #include<queue> #include<cmath> using namespace std; typedef long long int int64; struct{int a, b, val;}lks[500000]; int lkcnt; int _n; vector<int> to[30000]; int cur[30000]; void init(int n){ lkcnt = 0; _n = n; for(int lx = 0;lx < n;lx++) to[lx].clear(); return; } void addlink(int a, int b, int ab, int ba = 0){ lks[lkcnt].a = a, lks[lkcnt].b = b, lks[lkcnt].val = ab; to[a].push_back(lkcnt++); lks[lkcnt].a = b, lks[lkcnt].b = a, lks[lkcnt].val = ba ; to[b].push_back(lkcnt++); return; } int dis[30000], que[30000]; int bfs(int s, int t){ int n = _n; for(int lx = 0;lx < n;lx++) dis[lx] = -1; int qs = 0, qe = 1; dis[s] = 0, que[0] = s; while(qs < qe){ int g = que[qs++]; for(int lx = 0;lx < to[g].size();lx++){ int lind = to[g][lx]; int pind = lks[lind].b; if(dis[pind] != -1) continue; if(lks[lind].val == 0) continue; dis[pind] = dis[g] + 1; que[qe++] = pind; } } return dis[t] != -1; } bool vis[30000]; int dfs(int vv, int df, int s, int t){ if(vv == t) return df; if(vis[vv]) return 0; vis[vv] = true; for(int& lx = cur[vv];lx < to[vv].size();lx++){ int lind = to[vv][lx]; int pind = lks[lind].b; if(lks[lind].val == 0) continue; if(dis[pind] != dis[vv]+1) continue; int f = dfs(pind, min(lks[lind].val, df), s, t); if(f > 0){ lks[lind].val -= f; lks[lind^1].val += f; return f; } } return 0; } int dinic(int s, int t){ int f = 0, df; while(bfs(s, t)){ memset(cur, 0, sizeof(cur)); for(;;){ memset(vis, 0, sizeof(vis)); df = dfs(s, 1000000000, s, t); if(df == 0) break; f += df; } } return f; } int main() { int n, m, a, b, w; scanf("%d %d", &n, &m); init(n+2); for(int lx = 0;lx < n;lx++){ scanf("%d %d", &a, &b); addlink(0, lx+1, a); addlink(lx+1, n+1, b); } for(int lx = 0;lx < m;lx++){ scanf("%d %d %d", &a, &b, &w); addlink(a, b, w, w); } printf("%d\n", dinic(0, n+1)); return 0; }
2014年10月31日 星期五
POJ 3469 Dual Core CPU
把常數壓一壓就好了
UVAOJ 1515 Pool construction
給每個格子一個點
連到s代表選地,連到t代表選洞
相鄰的再連一條cost為b的無向邊
做最大流
連到s代表選地,連到t代表選洞
相鄰的再連一條cost為b的無向邊
做最大流
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<vector> #include<utility> #include<map> #include<set> #include<queue> #include<cmath> #define INF 10000000 using namespace std; typedef long long int int64; struct{ int a, b, val; }lks[100000]; int lks_cnt; vector<int> to[100000]; int _n; void init(int n){ _n = n; for(int lx = 0;lx < n;lx++){ to[lx].clear(); } lks_cnt = 0; return; } void addlink(int a, int b, int ab){ //printf("link %d -> %d with %d\n", a, b, ab); lks[lks_cnt].a = a, lks[lks_cnt].b = b, lks[lks_cnt].val = ab; to[a].push_back(lks_cnt++); lks[lks_cnt].a = b, lks[lks_cnt].b = a, lks[lks_cnt].val = 0; to[b].push_back(lks_cnt++); return; } int dis[100000], que[100000] ; int bfs(int s, int t){ int n = _n; for(int lx = 0;lx < n;lx++){ dis[lx] = -1; } dis[s] = 0; int qs = 0, qe = 1; que[0] = s; while(qs < qe){ int g = que[qs++]; for(int lx = 0;lx < to[g].size();lx++){ int lind = to[g][lx]; int pind = lks[lind].b; if(dis[pind] != -1) continue; if(lks[lind].val == 0) continue; dis[pind] = dis[g]+1; que[qe++] = pind; } } return (dis[t] != -1); } bool vis[100000]; int dfs(int vv, int df, int s, int t){ //printf("dfs: %d\n", vv); //for(int lx = 0;lx/100000 < 100;lx++); if(vv == t) return df; if(vis[vv]) return 0; vis[vv] = true; for(int lx = 0;lx < to[vv].size();lx++){ int lind = to[vv][lx]; int pind = lks[lind].b; if(lks[lind].val == 0) continue; if(dis[pind] != dis[vv] +1) continue; int f = dfs(pind, min(df, lks[lind].val), s, t); if(f > 0){ lks[lind].val -= f; lks[lind^1].val += f; return f; } } return 0; } int dinic(int s, int t){ int f = 0, df = 0; while(bfs(s, t)) for(;;){ memset(vis, 0, sizeof(vis)); int df = dfs(s, 1000000000, s, t); if(df == 0) break; f += df; } return f; } int ctr = 0; int get_ind(){return ctr++;} int main() { int T;scanf("%d", &T); while(T--){ int w, h; scanf("%d %d", &w, &h); int d, f, b;scanf("%d %d %d", &d, &f, &b); int Map[60][60]; for(int lx = 0;lx < h;lx++){ char str[1000]; scanf("%s", str); for(int ly = 0;ly < w;ly++) Map[lx][ly] = str[ly] == '#'; } ctr = 0; int ss = get_ind(), tt = get_ind(); int map_nod[100][100]; for(int lx = 0;lx < h;lx++) for(int ly = 0;ly < w;ly++) map_nod[lx][ly] = get_ind(); int ind_count = get_ind(); init(ind_count); for(int lx = 0;lx < h;lx++){ for(int ly = 0;ly < w;ly++) { if((lx == 0) or (lx == h-1) or (ly == 0) or (ly == w-1)){ if(Map[lx][ly]){ addlink(map_nod[lx][ly], tt, INF); }else{ addlink(ss, map_nod[lx][ly], f); addlink(map_nod[lx][ly], tt, INF); } }else{ if(Map[lx][ly]){ addlink(map_nod[lx][ly], tt, d); }else{ addlink(ss, map_nod[lx][ly], f); } } } } for(int lx = 0;lx < h-1;lx++){ for(int ly = 0;ly < w;ly++){ //down addlink(map_nod[lx][ly], map_nod[lx+1][ly], b); addlink(map_nod[lx+1][ly], map_nod[lx][ly], b); } } for(int lx = 0;lx < h;lx++){ for(int ly = 0;ly < w-1;ly++){ //down addlink(map_nod[lx][ly], map_nod[lx][ly+1], b); addlink(map_nod[lx][ly+1], map_nod[lx][ly], b); } } printf("%d\n", dinic(ss, tt)); } return 0; }
2014年10月27日 星期一
UVA 10330 - Power Transmission
點流量
#include<cstdio> #include<cstdlib> #include<vector> #define INF 100000000 using namespace std; vector<int> to[1000]; struct{ int a, b, val;} es[10001]; int ecnt; int _n; void init(int n){ _n = n; for(int lx = 0;lx <= n;lx++) to[lx].clear(); ecnt = 0; return; } void addedge(int a, int b, int val){ //printf("%d~%d = %d\n", a, b, val); es[ecnt].a = a, es[ecnt].b = b, es[ecnt].val = val; to[a].push_back(ecnt++); es[ecnt].a = b, es[ecnt].b = a, es[ecnt].val = 0; to[b].push_back(ecnt++); return; } int que[10000]; int frm[10000]; int vis[10000]; int pth[10000]; int pathcnt; int bfs(int s, int t){ int n = _n; for(int lx = 0;lx <= n;lx++) frm[lx] = -1, vis[lx] =0; int qs = 0, qe = 1; que[0] = s, vis[s] = 1; while(qs < qe){ int g = que[qs++]; for(int lx = 0;lx < to[g].size();lx++){ int lind = to[g][lx]; int pind = es[lind].b; if(vis[pind]) continue; if(es[lind].val <= 0) continue; frm[pind] = lind; que[qe++] = pind; vis[pind] = 1; } } if(vis[t] == -1) return 0; int pp = t; pathcnt = 0; int min_val = INF; while(pp != s){ int lind = frm[pp]; pth[pathcnt++] = lind; min_val = min(min_val, es[lind].val); pp = es[lind].a; } for(int lx = 0;lx < pathcnt;lx++){ int lind = pth[lx]; es[lind].val -= min_val; es[lind^1].val += min_val; } return min_val; } int Ekarp(int s, int t){ int f = 0, df = 1; while(df){ df = bfs(s, t); f += df; } return f; } int now_ind; int get_ind(){return now_ind++;} int main() { int n; while(scanf("%d", &n) == 1){ int pmax[1000] = {0}; int mat[101][101] = {0}; int ss, tt; int starr[100]; for(int lx = 0;lx < n;lx++) scanf("%d", pmax+lx); int m; scanf("%d", &m); while(m--){ int a, b, val; scanf("%d %d %d", &a, &b, &val); mat[a-1][b-1] += val; } scanf("%d %d", &ss, &tt); for(int lx = 0;lx < ss+tt;lx++){ scanf("%d", starr+lx); starr[lx]--; } now_ind = 0; int ms = get_ind(), mt = get_ind(); //printf("ms %d, mt %d\n", ms, mt); int mpin[101], mpout[101]; for(int lx = 0;lx < n;lx++) mpin[lx] = get_ind(), mpout[lx] = get_ind(); init(get_ind()); for(int lx = 0;lx < ss;lx++) addedge(ms, mpin[starr[lx]], INF); for(int lx = 0;lx < tt;lx++) addedge(mpout[starr[ss+lx]], mt, INF); for(int lx = 0;lx < n;lx++) addedge(mpin[lx], mpout[lx], pmax[lx]); for(int lx = 0;lx < n;lx++) for(int ly = 0;ly < n;ly++) if(mat[lx][ly]) addedge(mpout[lx], mpin[ly], mat[lx][ly]); printf("%d\n", Ekarp(ms, mt)); } return 0; }
訂閱:
文章 (Atom)