博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【UVA11478】Halum (最短路解差分约束)
阅读量:5300 次
发布时间:2019-06-14

本文共 2716 字,大约阅读时间需要 9 分钟。

题目:

Sample Input

2 1
1 2 10
2 1
1 2 -10
3 3
1 2 4
2 3 2
3 1 5
4 5
2 3 4
4 2 5
3 4 2
3 1 0
1 2 -1
Sample Output
Infinite
Infinite
3
1

 

题意:

  给定一个有向图,每条边都有一个权值。每次你可以选择一个结点v和一个整数d,把所有以v为终点的边的权值减小d,把所有以v为起点的边的权值增加d,最后让所有边的权值的最小值大于零且尽量大。

 

分析:

  因为不同的操作互不影响,因此可以按任意顺序实施这些操作。另外,对于同一个点的多次操作可以合并,因此可以令sum(u)为作用于结点u之上的所有d之和。这样,本题的目标就是确定所有的sum(u),使得操作之后所有边权的最小值尽量大。

  “最小值最大”又让我们想到使用二分答案的方法。二分答案x之后,问题转化为是否可以让操作完毕后每条边的权值均不小于x。对于边a->b,不难发现操作完毕后它的权值为w(a,b)+sum(a)-sum(b),因此每条边a->b都可以列出一个不等式w(a,b)+sum(a)-sum(b)>=x,移项得sum(b)-sum(a)<=w(a,b)-x。这样,我们实际得到一个差分约束系统。

  差分约束系统是指一个不等式组,每个不等式形如xj-xi<=bk,这里的bk是一些事先已知的常数。这个不等式类似于最短路中的不等式d[v]<=d[u]+w(u,v),我们可以用最短路算法求解:对于约束条件xj-xi<=bk,新建一条边i->j,(根据最短路性质可以证明在图无负环的情况下这个不等式是成立的)权值为bk。如果图中有负权环,则差分约束系统无解。

 

代码如下:

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 using namespace std; 8 #define Maxn 510 9 #define Maxm 4010 10 #define INF 0xfffffff 11 12 int n,m; 13 int first[Maxn],dis[Maxn],cnt[Maxn]; 14 bool bq[Maxn],inq[Maxn]; 15 16 struct node 17 { 18 int x,y,c,cc,next; 19 }t[Maxm];int len; 20 21 int mymax(int x,int y) { return x>y?x:y;} 22 23 void ins(int x,int y,int cc) 24 { 25 t[++len].x=x;t[len].y=y;t[len].cc=cc; 26 t[len].next=first[x];first[x]=len; 27 } 28 29 queue
q; 30 31 bool spfa(int s) 32 { 33 memset(inq,0,sizeof(inq)); 34 memset(dis,63,sizeof(dis)); 35 memset(cnt,0,sizeof(cnt)); 36 while(!q.empty()) q.pop(); 37 dis[s]=0;inq[s]=1;q.push(s); 38 while(!q.empty()) 39 { 40 int x=q.front();q.pop();inq[x]=0; 41 for(int i=first[x];i;i=t[i].next) 42 { 43 int y=t[i].y; 44 if(dis[y]>dis[x]+t[i].c) 45 { 46 dis[y]=dis[x]+t[i].c; 47 if(!inq[y]) 48 { 49 q.push(y); 50 inq[y]=1; 51 if(++cnt[y]>n+1) return 1; 52 } 53 } 54 } 55 } 56 return 0; 57 } 58 59 bool check(int x) 60 { 61 memset(bq,0,sizeof(bq)); 62 for(int i=1;i<=len-n;i++) t[i].c=t[i].cc-x; 63 if(spfa(n+1)) return 0; 64 /*for(int i=1;i<=n+1;i++) if(!bq[i]) 65 { 66 if(spfa(i)) return 0; 67 }*/ 68 return 1; 69 } 70 71 void ffind(int l,int r) 72 { 73 while(l
>1; 76 if(check(mid)) l=mid; 77 else r=mid-1; 78 } 79 printf("%d\n",l); 80 } 81 82 int main() 83 { 84 while(scanf("%d%d",&n,&m)!=EOF) 85 { 86 memset(first,0,sizeof(first)); 87 int mx=-INF;len=0; 88 for(int i=1;i<=m;i++) 89 { 90 int x,y,cc; 91 scanf("%d%d%d",&x,&y,&cc); 92 ins(x,y,cc); 93 mx=mymax(cc,mx); 94 } 95 for(int i=1;i<=n;i++) 96 { 97 ins(n+1,i,0);t[len].c=0; 98 } 99 if(check(mx+1)) {printf("Infinite\n");continue;}100 if(!check(1)) {printf("No Solution\n");continue;}101 ffind(1,mx);102 }103 return 0;104 }
[UVA11478]

 

2016-04-10 15:33:20

转载于:https://www.cnblogs.com/Konjakmoyu/p/5374271.html

你可能感兴趣的文章
如何改善下面的代码 领导说了很耗资源
查看>>
Quartus II 中常见Warning 原因及解决方法
查看>>
php中的isset和empty的用法区别
查看>>
Android ViewPager 动画效果
查看>>
pip和easy_install使用方式
查看>>
博弈论
查看>>
Redis sentinel & cluster 原理分析
查看>>
我的工作习惯小结
查看>>
把word文档中的所有图片导出
查看>>
浏览器的判断;
查看>>
ubuntu 18.04取消自动锁屏以及设置键盘快捷锁屏
查看>>
Leetcode 589. N-ary Tree Preorder Traversal
查看>>
thinking back no11
查看>>
机器学习/深度学习/其他开发环境搭建记录
查看>>
xml.exist() 实例演示
查看>>
判断是否为空然后赋值
查看>>
中标麒麟QT+ODBC+人大金仓开发环境配置
查看>>
zabbix监控日志文件
查看>>
正则表达式
查看>>
pip install torch on windows, and the 'from torch._C import * ImportError: DLL load failed:' s...
查看>>