题目:Halum
题意:给出一张带权的有向图(可能有负权),可以对任意一个点进行操作,选择一个整数d,使这个点的所有出边上的值增加d,入边上的值减少d,问可能出现的最大的最小边权(要求这个值为正整数)。
思路:
假设在同一个点上操作了两次,选的数是d1和d2,那么第一次把所有出边上的值增加d1,所有入边上的值减少d1,第二次把所有出边上的值增加d2,所有入边上的值减少d2。此时从整体上看,每条入边上的值共减少d1+d2,出边上的值增加d1+d2,也就相当于对这个点选择了d1+d2进行了一次操作。所以为了方便起见,可以不妨设对每个点只操作了一次(不操作相当于d=0)。此时,假设在第i个点上加了sum[i]。
二分最大的最小边权,设为p。对于每一条边x->y,改动后的边权w[x][y]+sum[x]-sum[y]>p,变形之后得sum[x]-sum[y]>p-w[x][y],即sum[y]-sum[x]<w[x][y]-p。此时就形成了一个每个不等式形如x-y<a的差分约束系统。
所以只用在原图中把每条边的权减去p,在图中用spfa判负权回路。如果存在负权回路,那么差分约束问题无解,当前的p比答案大;否则差分约束问题有解,当前的p小于等于答案。
如果p等于最大的边权值加1,差分约束系统仍有解,原问题的结为INF。如果p等于1时仍存在负权回路,那么原问题无解。
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 500
#define maxm 2700
struct Pair {
int x,y;
Pair(int xx=0,int yy=0) {
x=xx,y=yy;
}
};
int n,m;
vector<Pair> a[maxn+5];
void init() {
for(int i=1; i<=n; i++) a[i].clear();
}
int readin(int& r) {
for(int i=1; i<=m; i++) {
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
a[x].push_back(Pair(y,z));
r=max(z,r); //此处写错写成 r=max(y,r) QwQ……
}
}
bool spfa() {
queue<int> que;
int cnt[maxn+5]= {0};
int dist[maxn+5]= {0};
bool u[maxn+5]= {0};
for(int i=1; i<=n; i++) {
que.push(i);
dist[i]=0,u[i]=true;
}
while(!que.empty()) {
int h=que.front();
que.pop();
u[h]=false;
for(int i=0; i<a[h].size(); i++) {
int x=a[h][i].x;
int y=a[h][i].y;
if(dist[x]>dist[h]+y) {
dist[x]=dist[h]+y;
if(!u[x]) {
u[x]=true,que.push(x);
if(++cnt[x]>n) return false;
}
}
}
}
return true;
}
bool judge(int x) {
for(int i=1; i<=n; i++) {
for(int j=0; j<a[i].size(); j++) {
a[i][j].y-=x;
}
}
int ans=spfa();
for(int i=1; i<=n; i++) {
for(int j=0; j<a[i].size(); j++) {
a[i][j].y+=x;
}
}
return ans;
}
int binsearch(int l,int r) {
while(r-l>1) {
int mid=l+(r-l)/2;
if(judge(mid)) l=mid;
else r=mid;
}
if(judge(l+1)) l++;
if(!judge(l)) l--;
return l;
}
int main() {
while(~scanf("%d%d",&n,&m)) {
init();
int l=2,r=-10000;
readin(r);
if(judge(r+1)) {
printf("Infinite\n");
continue;
}
if(!judge(1)) {
printf("No Solution\n");
continue;
}
int ans=binsearch(l,r);
printf("%d\n",ans);
}
return 0;
}
本文介绍了一个名为Halum的问题解决方案,该问题涉及在带权有向图中通过调整节点权重来寻找可能的最大最小边权。文章详细阐述了解题思路及采用二分查找与SPFA算法判断可行解的过程。

被折叠的 条评论
为什么被折叠?



