题目: [CF Edu 80] Red-Blue Graph
链接:https://codeforces.com/contest/1288/problem/F
分析:
原来在费用流里必选一条边还能用-inf来控制,原谅我孤陋寡闻了
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 410;
const int MAXM = MAXN * 10;
const int inf = 1e6;
const LL INF = 1e18;
namespace NWF{
struct Edge {
int to, nxt;LL f, c;
} e[MAXM << 1];
int S, T, tot;
int ecnt, head[MAXN], cur[MAXN];LL dis[MAXN];
bool exist[MAXN];
queue<int> q;
void init(int _S, int _T, int _tot){
ecnt = 1; S = _S; T = _T; tot = _tot;
memset(head, 0, (tot + 1) * sizeof(int));
}
void addEdge(int u, int v, LL f, LL c) {
e[++ecnt] = (Edge) {v, head[u], f, c}; head[u] = ecnt;
e[++ecnt] = (Edge) {u, head[v], 0,-c}; head[v] = ecnt;
}
bool spfa() {
for(int i = 0;i <= tot; ++i){
dis[i] = INF; cur[i] = exist[i] = 0;
}
q.push(S);dis[S] = 0;exist[S] = 1;
while(!q.empty()) {
int u = q.front(), v; q.pop();exist[u] = 0;
for(int i = head[u]; i; i = e[i].nxt) {
if(e[i].f && dis[v = e[i].to] > dis[u] + e[i].c) {
dis[v] = dis[u] + e[i].c;
cur[v] = i;
if(!exist[v]) {
q.push(v);
exist[v] = 1;
}
}
}
}
return dis[T] != INF;
}
LL mcmf() {
LL cost = 0;
while(spfa() && dis[T] < 0) {
LL flow = INF;
for(int i = T; i != S; i = e[cur[i] ^ 1].to)
flow = min(flow, e[cur[i]].f);
for(int i = T; i != S; i = e[cur[i] ^ 1].to) {
e[cur[i]].f -= flow;
e[cur[i] ^ 1].f += flow;
}
cost += flow * dis[T];
}
return cost;
}
}
int msk[MAXN];
int main() {
int n1, n2, m, r, b, cnt = 0;
cin >> n1 >> n2 >> m >> r >> b;
string col1, col2;
cin >> col1;
NWF::init(0, n1 + n2 + 1, n1 + n2 + 2);
for(int i = 1; i <= n1; i++) {
if(col1[i-1]=='R') NWF::addEdge(NWF::S, i, 1, -inf) , cnt++;
if(col1[i-1]=='B') NWF::addEdge(i, NWF::T, 1, -inf) , cnt++;
if(col1[i-1]!='B') NWF::addEdge(NWF::S, i, inf, 0);
if(col1[i-1]!='R') NWF::addEdge(i, NWF::T, inf, 0);
}
cin >> col2;
for(int i = 1; i <= n2; i++) {
if(col2[i-1]=='R') NWF::addEdge(i+n1, NWF::T, 1, -inf), cnt++;
if(col2[i-1]=='B') NWF::addEdge(NWF::S, i+n1, 1, -inf), cnt++;
if(col2[i-1]!='B') NWF::addEdge(i+n1,NWF::T, inf, 0);
if(col2[i-1]!='R') NWF::addEdge(NWF::S,i+n1, inf, 0);
}
for(int i = 1, u, v; i <= m; i++) {
cin >> u >> v; v += n1;
NWF::addEdge(u, v, 1, r);
NWF::addEdge(v, u, 1, b);
msk[i] = NWF::ecnt - 3;
}
LL ans = NWF::mcmf()+(LL)cnt*inf;
if(ans >= inf) cout << "-1" <<endl;
else{
cout << ans << endl;
for(int i = 1; i <= m; i++)
cout << (NWF::e[msk[i]].f == 0 ?'R': NWF::e[msk[i]+2].f==0?'B':'U');
printf("\n");
}
return 0;
}
来源:https://www.cnblogs.com/hjj1871984569/p/12235383.html