Codeforces 844F Anti-Palindromize 最小費用流
阿新 • • 發佈:2019-04-07
ant second true min oid char make ret ali
Anti-Palindromize
想到網絡流就差不多了, 拆拆點, 建建邊。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long usingnamespace std; const int N = 1500 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-9; const double PI = acos(-1); int edgenum, S, T; int head[N], dist[N], pre[N]; bool vis[N]; struct Edge { int from, to, cap, flow, cost, next; } edge[1000007]; void MCMFinit() { edgenum = 0; memset(head, -1, sizeof(head)); } void addEdge(int u, int v, int w, int c) { Edge E1 = {u, v, w, 0, c, head[u]}; edge[edgenum] = E1; head[u] = edgenum++; Edge E2 = {v, u, 0, 0, -c, head[v]}; edge[edgenum] = E2; head[v] = edgenum++; }bool SPFA(int s, int t) { queue<int> Q; memset(dist, INF, sizeof(dist)); memset(vis, false, sizeof(vis)); memset(pre, -1, sizeof(pre)); dist[s] = 0; vis[s] = true; Q.push(s); while(!Q.empty()) { int u = Q.front(); Q.pop(); vis[u] = false; for(int i = head[u]; i != -1; i = edge[i].next) { Edge E = edge[i]; if(dist[E.to] > dist[u] + E.cost && E.cap > E.flow) { dist[E.to] = dist[u] + E.cost; pre[E.to] = i; if(!vis[E.to]) { vis[E.to] = true; Q.push(E.to); } } } } return pre[t] != -1; } void MCMF(int s, int t, int &cost, int &flow) { flow = 0; cost = 0; while(SPFA(s, t)) { int Min = INF; for(int i = pre[t]; i != -1; i = pre[edge[i^1].to]) { Edge E = edge[i]; Min = min(Min, E.cap - E.flow); } for(int i = pre[t]; i != -1; i = pre[edge[i^1].to]) { edge[i].flow += Min; edge[i^1].flow -= Min; cost += edge[i].cost * Min; } flow += Min; } } int n; char s[N]; int a[N], b[N]; int cnt[100]; int main() { MCMFinit(); scanf("%d", &n); S = 0, T = (n / 2 + 1) * 26 + n + 1; int B = (n / 2 + 1); int G = (n / 2 + 1) * 26; scanf("%s", s + 1); for(int i = 1; i <= n; i++) scanf("%d", &b[i]); for(int i = 1; i <= n; i++) { a[i] = s[i] - ‘a‘ + 1; cnt[a[i]]++; } for(int i = 1, o = 1; i <= G; i += B, o++) { addEdge(S, i, cnt[o], 0); for(int j = 1; j < B; j++) { addEdge(i, i + j, 1, 0); int c1 = a[j] == o ? -b[j] : 0; int c2 = a[n - j + 1] == o ? -b[n - j + 1] : 0; addEdge(i + j, G + j, 1, c1); addEdge(i + j, G + n - j + 1, 1, c2); } } for(int i = 1; i <= n; i++) addEdge(G + i, T, 1, 0); int cost = 0, flow = 0; MCMF(S, T, cost, flow); printf("%d\n", -cost); return 0; } /* */
Codeforces 844F Anti-Palindromize 最小費用流