社区讨论
一点小疑惑
P1500[集训队互测 2000] 丘比特的烦恼参与者 2已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @losdqhc7
- 此快照首次捕获于
- 2023/11/10 16:52 2 年前
- 此快照最后确认于
- 2023/11/10 19:28 2 年前
我建好了边,可是应该怎么改变Dinic才行啊。 Dinic:
CPP//
// Created by lndff on 2023.11.09
//
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 210000;
const int M = 501000;
const int INF = 0x3f3f3f3f;
template <typename T> inline void read(T &x){
int w = 1;x = 0;char s;
while (!isdigit(s = getchar())) if (s == '-') w = -1;
while (isdigit(s)) x = (x << 3) + (x << 1), x += s - '0', s = getchar();
x *= w;
}
int n, s, t, tot = 1, k, TOT;
int head[N], Next[M << 1], ver[M << 1], love[100][100], ANS;
LL d[N], w[M << 1], c[M << 1];
LL ans;
string name[100];
map<string, pair<int, int>>mp;
unordered_map<string, int> hax;
bool vis[N << 1];
void deals(string &s){
for (auto i : s){
if (i < 'a') i += 'a' - 'A';
}
}
void add(int u, int v, LL ww, LL C){
ver[++tot] = v;
w[tot] = ww;
Next[tot] = head[u];
head[u] = tot;
c[tot] = C;
// cout << ww << " ";
}
inline int bfs(){
for (register int i = 1; i <= n * 2 + 2; d[i] = INF, i++);
queue<int> q;
q.push(s);
d[s] = 0;
while (!q.empty()){
int x = q.front();
q.pop();
for (int i = head[x]; i; i = Next[i]){
if (w[i] > 0 && d[ver[i]] == INF){
q.push(ver[i]);
d[ver[i]] = d[x] + 1;
if (ver[i] == t) return 1;
}
}
}
return 0;
}
inline int dfs(int x, LL sumflow){
if (x == t) return sumflow;
LL res, ret = 0;
vis[x] = 1;
for (int i =head[x]; i && sumflow; i = Next[i]){
if (w[i] && (d[ver[i]] == d[x] + w[i]) && !vis[ver[i]]){
res = dfs(ver[i], min(sumflow, w[i]));
if (!res) d[ver[i]] = INF;
w[i] -= res;
w[i ^ 1] += res;
ret += res;
sumflow -= res;
ANS += c[i] * res;
}
}
return ret;
}
signed main(){
read(k);
read(n);
int ww;
for (int i = 1, x, y; i <= n; i++){
cin >> x >> y >> name[i];
deals(name[i]);
mp[name[i]] = {x, y};
hax[name[i]] = i;
}
for (int i = 1, x, y; i <= n; i++){
cin >> x >> y >> name[i + n];
deals(name[i + n]);
mp[name[i + n]] = {x, y};
hax[name[i + n]] = i + n;
}
string name1, name2;
cin >> name1;
while (name1 != "End"){
cin >> name2;cin >> ww;
deals(name1);deals(name2);
int xx = mp[name1].first, xy = mp[name1].second, yx = mp[name2].first, yy = mp[name2].second;
if ((xx - yx) * (xx - yx) + (xy - yy) * (xy - yy) <= k * k){
int man = hax[name1], woman = hax[name2];
if (man > woman) swap(man, woman);
love[man][woman] = max(love[man][woman], ww);
}
cin >> name1;
}
for (int i = 1; i <= n; i++){
for (int j = n + 1; j <= n * 2; j++){
if (!love[i][j]){
int xx = mp[name[i]].first, xy = mp[name[i]].second, yx = mp[name[j]].first, yy = mp[name[j]].second;
if ((xx - yx) * (xx - yx) + (xy - yy) * (xy - yy) <= k * k){
love[i][j] = 1;
}
}
}
}
for (int i = 1; i <= n; i++){
for (int j = n + 1; j <= n * 2; j++){
// cout << "love[i][j]";
int xx = mp[name[i]].first, xy = mp[name[i]].second, yx = mp[name[j]].first, yy = mp[name[j]].second;
if ((xx - yx) * (xx - yx) + (xy - yy) * (xy - yy) <= k * k){
add(i, j, 1, love[i][j]), add(j, i, 0, -love[i][j]);
}
}
}
s = n * 2 + 1;t = n * 2 + 2;
for (int i = 1; i <= n; i++) add(s, i, 1, 0), add(i, s, 0, 0);
for (int i = n + 1; i <= n * 2; i++) add(i, t, 1, 0), add(t, i, 0, 0);
while (bfs()) {ans += dfs(s, INF);}
return 0 * printf("%d", ANS);
}
/*
2
3
0 0 Adam
1 1 Jack
0 2 George
1 0 Victoria
0 1 Susan
1 2 Cathy
Adam Cathy 100
Susan George 20
George Cathy 40
Jack Susan 5
Cathy Jack 30
Victoria Jack 20
Adam Victoria 15
End
*/
样例怎么测都只有60,似乎是因为边权变为一之后就没法反悔了。。。
回复
共 4 条回复,欢迎继续交流。
正在加载回复...