BZOJ 3118 Orz the MST 线性规划
来源:互联网 发布:华为网络认证多少钱 编辑:程序博客网 时间:2024/06/13 17:06
题意:链接
方法:线性规划
解析:
这道题我也是orz了。
刚开始脑抽,仅仅是认为所有标号为1的边都比标号为0的边小即可。
后来与140142讨论了下发现我俩都犯好sb的错误=-=
这个图也是建了一阵子。
回忆之前做过的有关一个无向联通图中,一个边在最小生成树上,必要条件是该边构成的环中,这一边一定不是最大值。
这样的话,题中既然给了在树上的边。
并且很显然树上的边只能增加,不在树上的边只能减小。
所以我们不妨设Xi 代表第i条边的变化值
那么我们可以重新显然定义代价Ci 。
结合之前的结论
编号为j的标号为0的一条边,与树中的i,k边形成环。
则有如下限制
Xj+Wj>=Wi−Xi
Xj+Wj>=Wk−Xk
则
Xi+Xj>=Wi−Wj
Xk+Xj>=Wk−Wj
我们可以列出所有诸如此类的限制,并且对于本题的数据,该限制不超过4000。
我们的目标函数是什么?
最小化∑mi=1Xi∗Ci
这种形式是不是有点眼熟?
是的,直接用对偶原理即可求解。
然而,该题仍有一种较神的写法博主没有写过
就是这种没有基本可行解的线性规划,我们可以设一个辅助变量来求解。
代码:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 310#define M 1010#define INF 0x7f7f7f7fusing namespace std;double a[M][M<<2];int st[N];struct line{ int u,v,w,ff,a,b;}l[M];int head[N],cnt,n,m,top,tot;struct node{ int from,to,ff,no,a,b,next;}edge[M<<1];void init(){ memset(head,-1,sizeof(head));cnt=1;}void edgeadd(int from,int to,int ff,int no){ edge[cnt].from=from,edge[cnt].to=to,edge[cnt].ff=ff,edge[cnt].no=no; edge[cnt].next=head[from]; head[from]=cnt++;}void dfs(int now,int fa,int e,int edge0){ if(now==e) { while(top) { tot++; int no=st[top--]; a[no][tot]=1; a[edge0][tot]=1; a[0][tot]=l[no].w-l[edge0].w; } return; } for(int i=head[now];i!=-1;i=edge[i].next) { int to=edge[i].to; if(to==fa)continue; st[++top]=edge[i].no; dfs(to,now,e,edge0); st[top--]=0; }}int check(){ for(int i=1;i<=tot;i++) if(a[0][i]>0)return i; return 0;}void Simplex(){ while(int t=check()) { double limit=INF; int choseline; for(int i=1;i<=m;i++) { if(a[i][t]<=0)continue; else if(a[i][0]/a[i][t]<limit)limit=a[i][0]/a[i][t],choseline=i; } if(limit==INF){a[0][0]=INF;break;} double di=a[choseline][t]; for(int i=0;i<=tot;i++) { if(i==t)a[choseline][i]/=di; a[choseline][i]/=di; } for(int i=0;i<=m;i++) { if(i==choseline||a[i][t]==0)continue; if(i==0)a[i][0]+=a[i][t]*a[choseline][0]; else a[i][0]-=a[i][t]*a[choseline][0]; double l=a[i][t]; for(int j=1;j<=tot;j++) { if(j==t)a[i][j]=-l*a[choseline][j]; else a[i][j]-=l*a[choseline][j]; } } }}int main(){ init(); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v,w,ff,A,b,no; scanf("%d%d%d%d%d%d",&u,&v,&w,&ff,&A,&b); l[i].u=u,l[i].v=v,l[i].w=w,l[i].ff=ff,l[i].a=A,l[i].b=b; if(ff)a[i][0]=b; else a[i][0]=A; if(ff)edgeadd(u,v,ff,i),edgeadd(v,u,ff,i); } for(int i=1;i<=m;i++) { if(l[i].ff==0) { top=0; dfs(l[i].u,0,l[i].v,i); } } Simplex(); printf("%.0lf\n",a[0][0]);}
0 0
- BZOJ 3118 Orz the MST 线性规划
- bzoj-3118 Orz the MST
- bzoj 3118: Orz the MST (单纯形)
- [最大费用可行流 || 单纯形] BZOJ 3118 Orz the MST
- BZOJ3118: Orz the MST
- bzoj3118 Orz the MST
- [BZOJ3118]Orz the MST --ORZ the Simplex
- [BZOJ3118]Orz the MST(单纯形)
- [单纯形+对偶] BZOJ3118: Orz the MST
- [对偶 KM算法 生成树 || 最大费用可行流 || 线性规划] BZOJ 1937 [Shoi2004]Mst 最小生成树
- bzoj 1283(线性规划)
- BZOJ 3550 [ONTAK2010]Vacation 线性规划
- bzoj 1061(线性规划+费用流)
- Orz
- orz
- ORZ
- ...Orz
- Orz
- hdu1042
- Java中数据解析之_JSON(Android官方内置解析器)
- CRB and String
- 深入分析C++中deque的使用
- 继承详解
- BZOJ 3118 Orz the MST 线性规划
- 如何在服务端保存用户上传的图片文件
- hihoCoder 1079 离散化(线段树离散化)
- 南邮新生赛题解
- 《Java设计模式》之访问者模式
- SPOJ 题目705 New Distinct Substrings(后缀数组,求不同的子串个数)
- VS报错:Oracle.ManagedDataAccess.Client.OracleException: ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值
- hdoj-1869 六度分离【最短路径--dijkstra&&spfa&&floyd】
- ckeditor若文件上传的不是图片类型则显示不成功