UVA11248 Frequency Hopping 题解
先最大流一次,如果此时流量大于等于
如果不行,我们考虑枚举每一条流满的边,将容量设置为
这样我们每次更改容量,重新跑最大流即可。
#pragma GCC optimize("-Ofast,fast-math,-inline")
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
#define int long long
const int N = 3e4 + 5;
int n, m, p;
int e[N], h[N], c[N], ne[N], idx;
int e2[N], h2[N], c2[N], ne2[N], idx2;
int num[N];
inline void add(int u, int v, int w)
{
e[idx] = v, c[idx] = w, ne[idx] = h[u], h[u] = idx++;
e[idx] = u, c[idx] = 0, ne[idx] = h[v], h[v] = idx++;
}
inline void add2(int u, int v, int w)
{
e2[idx2] = v, c2[idx2] = w, ne2[idx2] = h2[u], h2[u] = idx2++;
e2[idx2] = u, c2[idx2] = 0, ne2[idx2] = h2[v], h2[v] = idx2++;
}
int U[N], V[N];
class Maximum_Flow
{
public:
int d[N], cur[N];
bool bfs()
{
for (int i = 1; i <= n; i++) d[i] = -1, cur[i] = -1;
queue<int> q;
d[1] = 0;
cur[1] = h2[1];
q.push(1);
while (q.size())
{
int u = q.front();
q.pop();
for (int i = h2[u]; ~i; i = ne2[i])
{
int j = e2[i];
if (d[j] == -1 && c2[i] > 0)
{
d[j] = d[u] + 1;
cur[j] = h2[j];
if (j == n) return 1;
q.push(j);
}
}
}
return 0;
}
int dfs(int u, int lim)
{
if (u == n) return lim;
int sum = 0;
for (int i = cur[u]; ~i && sum < lim; i = ne2[i])
{
cur[u] = i;
int j = e2[i];
if (d[j] == d[u] + 1 && c2[i] > 0)
{
int q = dfs(j, min(lim - sum, c2[i]));
//printf("!: %lld %lld %lld %lld\n", u, j, p, min(lim - sum, c2[i]));
if (!q) d[j] = -1;
else
{
sum += q;
c2[i] -= q;
c2[i ^ 1] += q;
}
}
}
return sum;
}
int dinic()
{
int res = 0;
while (bfs())
{
int k;
while (k = dfs(1, 2e9)) res += k;
}
return res;
}
}DNC;
int c3[N];
signed main()
{
int css = 0;
while (scanf("%lld%lld%lld", &n, &m, &p))
{
css++;
if (!n && !m && !p) break;
for (int i = 0; i <= n; i++)
{
h[i] = h2[i] = -1;
}
idx = idx2 = 0;
for (int i = 1; i <= m; i++)
{
int u, v, w;
scanf("%lld%lld%lld", &u, &v, &w);
add(u, v, w);
add2(u, v, w);
num[i] = idx2 - 2;
U[i] = u, V[i] = v;
}
vector<pair<int, int> > ans;
int ps = DNC.dinic();
if (ps >= p)
{
printf("Case %lld: possible\n", css);
continue;
}
else
{
for (int i = 0; i < N; i++) c3[i] = c2[i];
for (int i = 1; i <= m; i++)
{
int g = num[i];
if (c3[g] == 0)
{
// 流满,将这条边容量改为 INF
for (int j = 0; j <= idx; j++)
{
c2[j] = c[j];
}
c2[g] = 2e9;
if (DNC.dinic() >= p)
{
ans.emplace_back(make_pair(U[i], V[i]));
}
}
}
}
sort(ans.begin(), ans.end());
if (ans.size() == 0) printf("Case %lld: not possible\n", css);
else
{
printf("Case %lld: possible option:", css);
for (int i = 0; i + 1 < ans.size(); i++)
{
printf("(%lld,%lld),", ans[i].first, ans[i].second);
}
printf("(%lld,%lld)\n", ans.back().first, ans.back().second);
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现