POJ 1149 PIGS
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<cctype> #include<set> #include<queue> #include<vector> #include<map> using namespace std; typedef long long LL; inline int read() { int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; } const int N = 10005, INF = 1e9; struct Edge{ int to, nxt, cap; }e[N << 1]; int head[N], cur[N], dis[N], q[N], En = 1, S, T; void add_edge(int u,int v,int w) { // cout << u << " " << v << " " << w << "\n"; ++En; e[En].to = v; e[En].nxt = head[u]; e[En].cap = w; head[u] = En; ++En; e[En].to = u; e[En].nxt = head[v]; e[En].cap = 0; head[v] = En; } bool bfs() { for (int i = 0; i <= T; ++i) dis[i] = -1, cur[i] = head[i]; int L = 1, R = 0; q[++R] = S; dis[S] = 0; while (L <= R) { int u = q[L ++]; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (dis[v] == -1 && e[i].cap > 0) { dis[v] = dis[u] + 1; q[++R] = v; if (v == T) return 1; } } } return 0; } int dfs(int u,int flow) { if (u == T) return flow; int used = 0, t; for (int &i = cur[u]; i; i = e[i].nxt) { int v = e[i].to; if (dis[v] == dis[u] + 1 && e[i].cap > 0) { t = dfs(v, min(e[i].cap, flow - used)); if (t > 0) { used += t, e[i].cap -= t, e[i ^ 1].cap += t; if (used == flow) break; } } } if (used != flow) dis[u] = -1; return used; } int dinic() { int ans = 0; while (bfs()) ans += dfs(S, INF); return ans; } vector<int> vec[N]; int w[N], cnt[N]; int main() { //freopen("1.txt", "r", stdin); int m = read(), n = read(); for (int i = 1; i <= m; ++i) w[i] = read(); for (int i = 1; i <= n; ++i) { int t = read(); while (t--) { int u = read(); vec[u].push_back(i); } cnt[i] = read(); } S = 0; T = n + 1; for (int i = 1; i <= n; ++i) add_edge(i, T, cnt[i]); for (int i = 1; i <= m; ++i) { if (vec[i].size() == 0) continue; add_edge(S, vec[i][0], w[i]); for (int j = 1; j < vec[i].size(); ++j) { add_edge(vec[i][j - 1], vec[i][j], INF); } } cout << dinic(); return 0; }
POJ 2699 The Maximum Number of Strong Kings
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<cctype> #include<set> #include<queue> #include<vector> #include<map> using namespace std; typedef long long LL; inline int read() { int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; } const int N = 2005, INF = 1e9; struct Edge{ int to, nxt, cap; }e[N << 1]; int head[N], cur[N], dis[N], q[N], En = 1, S, T; void add_edge(int u,int v,int w) { // cout << u << " " << v << " " << w << "\n"; ++En; e[En].to = v; e[En].nxt = head[u]; e[En].cap = w; head[u] = En; ++En; e[En].to = u; e[En].nxt = head[v]; e[En].cap = 0; head[v] = En; } bool bfs() { for (int i = 0; i <= T; ++i) dis[i] = -1, cur[i] = head[i]; int L = 1, R = 0; q[++R] = S; dis[S] = 0; while (L <= R) { int u = q[L ++]; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (dis[v] == -1 && e[i].cap > 0) { dis[v] = dis[u] + 1; q[++R] = v; if (v == T) return 1; } } } return 0; } int dfs(int u,int flow) { if (u == T) return flow; int used = 0, t; for (int &i = cur[u]; i; i = e[i].nxt) { int v = e[i].to; if (dis[v] == dis[u] + 1 && e[i].cap > 0) { t = dfs(v, min(e[i].cap, flow - used)); if (t > 0) { used += t, e[i].cap -= t, e[i ^ 1].cap += t; if (used == flow) break; } } } if (used != flow) dis[u] = -1; return used; } int dinic() { int ans = 0; while (bfs()) ans += dfs(S, INF); return ans; } int n, tot, a[N], id[N][N]; bool solve(int k) { En = 1; memset(head, 0, sizeof(head)); S = 0; T = n + tot + 1; for (int i = 1; i <= n; ++i) add_edge(S, i, a[i]); for (int i = n + 1; i <= n + tot; ++i) add_edge(i, T, 1); for (int i = 1; i <= n; ++i) { for (int j = i + 1; j <= n; ++j) { if (i >= n - k + 1 && a[i] < a[j]) add_edge(i, id[i][j] + n, 1); else add_edge(i, id[i][j] + n, 1), add_edge(j, id[i][j] + n, 1); } } return dinic() == tot; } void solve() { n = tot = 0; string s; getline(cin, s); int now = 0; // for (int i = 0; i < (int)s.size(); ++i) { // if (s[i] == ' ') a[++n] = now, now = 0; // else now = now * 10 + s[i] - '0'; // } // a[++n] = now; for (int i = 0; i < (int)s.size(); ++i) { // 注意此处的读入!!!不要向上面一样读入!!! if (isdigit(s[i])) { now = 0; while (i < s.size() && isdigit(s[i])) { now = now * 10 + (s[i] - '0'); i ++; } i --; a[++n] = now; } } for (int i = 1; i <= n; ++i) for (int j = i + 1; j <= n; ++j) id[i][j] = id[j][i] = ++tot; for (int i = n; i >= 1; --i) if (solve(i)) { printf("%d\n", i); return ; } puts("0"); } int main() { int T = read(); for (; T--; ) solve(); return 0; }
ZOJ 2760 How Many Shortest Path
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<cctype> #include<set> #include<queue> #include<vector> #include<map> using namespace std; typedef long long LL; inline int read() { int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; } const int N = 2005, INF = 1e9; struct Edge{ int to, nxt, cap; }e[30005]; int head[N], cur[N], dis[N], q[N], En = 1, S, T, n; void add_edge(int u,int v,int w) { // printf("%d %d %d\n", u, v, w); ++En; e[En].to = v; e[En].nxt = head[u]; e[En].cap = w; head[u] = En; ++En; e[En].to = u; e[En].nxt = head[v]; e[En].cap = 0; head[v] = En; } bool bfs() { for (int i = 1; i <= n; ++i) dis[i] = -1, cur[i] = head[i]; int L = 1, R = 0; q[++R] = S; dis[S] = 0; while (L <= R) { int u = q[L ++]; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (dis[v] == -1 && e[i].cap > 0) { dis[v] = dis[u] + 1; q[++R] = v; if (v == T) return 1; } } } return 0; } int dfs(int u,int flow) { if (u == T) return flow; int used = 0, t; for (int &i = cur[u]; i; i = e[i].nxt) { int v = e[i].to; if (dis[v] == dis[u] + 1 && e[i].cap > 0) { t = dfs(v, min(e[i].cap, flow - used)); if (t > 0) { used += t, e[i].cap -= t, e[i ^ 1].cap += t; if (used == flow) break; } } } if (used != flow) dis[u] = -1; return used; } int dinic() { int ans = 0; while (bfs()) ans += dfs(S, INF); return ans; } int g[N][N], t[N][N]; void solve() { En = 1; memset(head, 0, sizeof(head)); if (S == T) { puts("inf"); return ; } for (int k = 1; k <= n; ++k) for (int i = 1;i <= n; ++i) for (int j = 1; j <= n; ++j) if (g[i][k] != -1 && g[k][j] != -1 && (g[i][k] + g[k][j] < g[i][j] || g[i][j] == -1)) g[i][j] = g[i][k] + g[k][j]; if (g[S][T] == -1) { puts("0"); return ; } for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) if (i != j && g[S][T] == g[S][i] + t[i][j] + g[j][T] && g[S][i] != -1 && g[j][T] != -1) add_edge(i, j, 1); printf("%d\n", dinic()); } int main() { // freopen("1.txt", "r", stdin); while (~scanf("%d", &n)) { for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) t[i][j] = g[i][j] = read(); for (int i = 1; i <= n; ++i) t[i][i] = g[i][i] = 0; S = read() + 1, T = read() + 1; solve(); } return 0; }