Description

Input

Output

Sample Input

3 3 1 3 100
1 2 3
2 3 4
1 3 5

Sample Output

8
9
12
-1
 
正解:暴搜+堆+最小割。
我觉得这道题真是毒瘤的可以了,正解要写$3$个程序才能过。。
 
$task1$:
$n<=10,m<=20$,暴搜即可。
 
$task2$:
$s$向除了$t$以外其他点连边,其他点向$t$连边。
最小割就是每个点的两条边取最小值然后相加。
考虑用堆来维护$k$小割,我们用类似于$k$短路的方法。
设每个点的两条边分别为$a$,$b$,且$a<=b$。
把每个点分为$3$级,$a$为$0$级,$b$为$1$级,$a+b$为$2$级。
我们作一个差,把$b-a$和$a$存起来,然后按照两个关键字从小到大排序。
我们发现,每个点只要升级就是加上$b-a$或$a$就行了。
那么对于每个点,有$3$种选择:
1.当前点升级;
2.当前点降级,后面那个点升级;
3.后面那个点升级。
然后就很好求出答案了。注意一个细节,就是操作$2$只在当前点为$1$级时考虑。因为从$2$级降到$1$级,后面那个点升级,这样会与操作$3$重复。
 
$task3$:
$n,m,k$不大,没有特殊条件。
我们直接考虑$k$小割如何求,我们得到最小割以后,然后有两种选择:要么是把最小割中的某一条边换成另一边,要么直接加一条边。
用类似$k$短路的做法,我们可以强制选一条边,或强制不选一条边,然后考虑上面两种生成次小割的方法。
直接加一条边就枚举不在割集的最小边加入就行了。
对于第一种情况,我们要删掉割集的一条边,那么显然要使$S,T$到两个割点必须不连通。
那么我们对于这两个割点,对$S,T$跑最小割,求出最小的最小割,然后加上这个最小割就行了。
不过细节巨多,所以我基本上是抄的代码。。
 
 //It is made by wfj_2048~
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define inf (1<<28)
#define il inline
#define RG register
#define ll long long using namespace std; struct E{ int u,v,w; }G[]; int n,m,k,S,T,mx; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
return q*x;
} namespace brute{ struct edge{ int nt,to; }g[]; int head[],vi[],vis[],top,num;
ll st[]; il void insert(RG int from,RG int to){
g[++num]=(edge){head[from],to},head[from]=num; return;
} il int find(RG int x,RG int T){
if (x==T) return ; vi[x]=; RG int v;
for (RG int i=head[x];i;i=g[i].nt){
v=g[i].to; if (vi[v]) continue;
if (find(v,T)) return ;
}
return ;
} il int check(){
memset(head,,sizeof(head)),num=;
for (RG int i=;i<=m;++i)
if (!vis[i]) insert(G[i].u,G[i].v);
memset(vi,,sizeof(vi)); return !find(S,T);
} il void dfs(RG int x,RG ll tot){
if (x>m){
if (check()) st[++top]=tot;
return;
}
vis[x]=,dfs(x+,tot+G[x].w);
vis[x]=,dfs(x+,tot); return;
} int main(){
dfs(,),sort(st+,st+top+);
for (RG int i=;i<=top && i<=k;++i) printf("%lld\n",st[i]);
if (top<k) puts("-1"); return ;
} } namespace heap{ struct data{
ll val; int i,level;
il bool operator < (const data &a) const{ return val>a.val; }
}; struct node{ ll a,b; }e[]; priority_queue <data> Q; ll mincut; il int cmp(const node &x,const node &y){
if (x.a==y.a) return x.b<y.b; return x.a<y.a;
} int main(){
for (RG int i=,x;i<=m;++i){
x=G[i].u; if (x==S || x==T) x=G[i].v;
if (!e[x].a) e[x].a=G[i].w; else{
e[x].b=G[i].w;
if (e[x].a<e[x].b) swap(e[x].a,e[x].b);
mincut+=e[x].b,e[x].a-=e[x].b;
}
}
if (T==n) e[S]=e[n-],e[T]=e[n]; else e[S]=e[n],e[T]=e[n-];
n-=,--k,sort(e+,e+n+,cmp),printf("%lld\n",mincut);
Q.push((data){mincut+e[].a,,});
for (;k && !Q.empty();--k){
RG data x=Q.top(),tmp; Q.pop();
printf("%lld\n",x.val);
if (x.level<){
tmp.val=x.val+e[x.i].b;
tmp.i=x.i,tmp.level=x.level+,Q.push(tmp);
}
if (x.i<n && x.level==){
tmp.val=x.val-e[x.i].a+e[x.i+].a;
tmp.i=x.i+,tmp.level=,Q.push(tmp);
}
if(x.i<n){
tmp.val=x.val+e[x.i+].a;
tmp.i=x.i+,tmp.level=,Q.push(tmp);
}
}
if (k) puts("-1"); return ;
} } namespace kthcut{ #define M (3005)
#define N (60) int head[N],cur[N],havs[N],havt[N],ds[N],dt[N],d[N],vis[N],in[M],q[*M],num=; struct Graph{ struct edge{ int nt,to,flow,cap; }g[M]; il void insert(RG int from,RG int to,RG int cap){
g[++num]=(edge){head[from],to,,cap},head[from]=num; return;
} il int bfs(RG int S,RG int T){
memset(d,,sizeof(d)),d[S]=;
RG int h=,t=; q[t]=S;
while (h<t){
RG int x=q[++h],v;
for (RG int i=head[x];i;i=g[i].nt){
v=g[i].to;
if (!d[v] && g[i].cap>g[i].flow){
d[v]=d[x]+,q[++t]=v;
if (v==T) return ;
}
}
}
return d[T];
} il ll dfs(RG int x,RG int T,RG int a){
if (!a || x==T) return a; RG ll flow=,f;
for (RG int &i=cur[x],v;i;i=g[i].nt){
v=g[i].to;
if (d[v]==d[x]+ && g[i].cap>g[i].flow){
f=dfs(v,T,min(a,g[i].cap-g[i].flow));
if (!f){ d[v]=; continue; }
g[i].flow+=f,g[i^].flow-=f;
flow+=f,a-=f; if (!a) return flow;
}
}
return flow;
} il ll mincut(RG int S,RG int T){
RG ll cut=;
while (bfs(S,T)){
memcpy(cur,head,sizeof(head));
cut+=dfs(S,T,inf); if (cut>inf) return cut;
}
return cut;
} il void DFS(RG int x){
vis[x]=;
for (RG int i=head[x];i;i=g[i].nt)
if (g[i].cap>g[i].flow && !vis[g[i].to]) DFS(g[i].to);
return;
} il void getcut(){
memset(vis,,sizeof(vis)),memset(in,,sizeof(in)),DFS(S);
for (RG int i=;i<=m;++i) if (vis[G[i].u] && !vis[G[i].v]) in[i]=;
return;
} }Gra,lin1,lin2; struct node{ int must[M],stop[M],id,ww; ll val; il bool operator < (const node &a) const{ return val>a.val; } il void build(){
val=,lin1=Gra;
for (RG int i=;i<=m;++i)
if (must[i]) val+=G[i].w,lin1.g[i<<].cap=;
else if (stop[i]) lin1.g[i<<].cap=inf;
val+=lin1.mincut(S,T),lin1.getcut(),ww=inf,id=;
memset(havs,,sizeof(havs)),memset(havt,,sizeof(havt));
for (RG int i=;i<=m;++i){
if (must[i] || stop[i]) continue;
if (in[i]){
if (!havs[G[i].u]){
havs[G[i].u]=,lin2=lin1;
ds[G[i].u]=lin2.mincut(S,G[i].u);
}
if (!havt[G[i].v]){
havt[G[i].v]=,lin2=lin1;
dt[G[i].v]=lin2.mincut(G[i].v,T);
}
if (ds[G[i].u]<ww) ww=ds[G[i].u],id=i;
if (dt[G[i].v]<ww) ww=dt[G[i].v],id=i;
} else if (G[i].w<ww) ww=G[i].w,id=i;
}
val+=ww; return;
} }a,b; priority_queue <node> Q; int main(){
for (RG int i=;i<=m;++i){
Gra.insert(G[i].u,G[i].v,G[i].w);
Gra.insert(G[i].v,G[i].u,);
}
--k,lin1=Gra,printf("%lld\n",lin1.mincut(S,T));
a.build(); if (a.val<inf) Q.push(a);
for (;k && !Q.empty();--k){
a=b=Q.top(),Q.pop(),printf("%lld\n",a.val);
a.must[a.id]=,a.build(); if (a.val<inf) Q.push(a);
b.stop[b.id]=,b.build(); if (b.val<inf) Q.push(b);
}
if (k) puts("-1"); return ;
} } int main(){
#ifndef ONLINE_JUDGE
freopen("kthcut.in","r",stdin);
freopen("kthcut.out","w",stdout);
#endif
n=gi(),m=gi(),S=gi(),T=gi(),k=gi();
for (RG int i=;i<=m;++i)
G[i].u=gi(),G[i].v=gi(),G[i].w=gi(),mx=max(mx,G[i].w);
if (m<=) brute::main();
else if (n<= && k<= && mx<=) kthcut::main();
else heap::main();
return ;
}

bzoj3882 [Wc2015]K小割的更多相关文章

  1. WC2015 k小割(k短路+暴力+搜索)

    首先这道题不是非同一般的恶心,三个数据层次对应三个程序= = PROBLEM:http://uoj.ac/problems解法: 1~2直接暴力枚举边的选择与否+判断就行了 7~14可以发现是一个平面 ...

  2. UOJ71 【WC2015】k小割

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  3. [LeetCode] Kth Smallest Element in a Sorted Matrix 有序矩阵中第K小的元素

    Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth ...

  4. [LeetCode] Kth Smallest Element in a BST 二叉搜索树中的第K小的元素

    Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. Not ...

  5. POJ2828 Buy Tickets[树状数组第k小值 倒序]

    Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 19012   Accepted: 9442 Desc ...

  6. UVA11525 Permutation[康托展开 树状数组求第k小值]

    UVA - 11525 Permutation 题意:输出1~n的所有排列,字典序大小第∑k1Si∗(K−i)!个 学了好多知识 1.康托展开 X=a[n]*(n-1)!+a[n-1]*(n-2)!+ ...

  7. *HDU2852 树状数组(求第K小的数)

    KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  8. 数组中第K小的数字(Google面试题)

    http://ac.jobdu.com/problem.php?pid=1534 题目1534:数组中第K小的数字 时间限制:2 秒 内存限制:128 兆 特殊判题:否 提交:1120 解决:208 ...

  9. 数据结构2 静态区间第K大/第K小

    给定数组$A[1...N]$, 区间$[L,R]$中第$K$大/小的数的指将$A[L...R]$中的数从大到小/从小到大排序后的第$K$个. "静态"指的是不带修改. 这个问题有多 ...

随机推荐

  1. 安装openstack时遇到的错误

    学习opensatck的第一步是安装DevStack来进行本机操作 1. 下面命令没有权限,解决办法:切换到root用户下执行sudo -s echo "stack ALL=(ALL) NO ...

  2. Appium自动化—浅谈iOS自动化测试环境搭建

    在日常的测试工作中,我们会发现有些测试工作重复率极高,测试人员需要花费大量的时间进行这些重复性的测试,浪费了大量的人力与时间.若能够将常用的测试场景进行自动化,那必定能节省许多的人力与时间.作为一个初 ...

  3. 配置sudo访问

    具体操作步骤 1.首先我们建立一个账户,设置密码 [root@VM_0_13_centos home]# useradd 123 [root@VM_0_13_centos home]# passwd ...

  4. Linux 磁盘管理基础命令df,du,fdisk,mke2fs

    1.df:查看已挂载磁盘的总容量,使用容量和剩余容量等,默认以KB位单位显示 文件系统   容量         已用    可用       已用百分比  挂载点 df常用选项-i,-h,-k,-m ...

  5. 转 ORACLE约束总结

    https://www.cnblogs.com/kerrycode/archive/2012/05/13/2454614.html 你对ORACLE约束的了解如何?比较模糊还是相当透彻?如果你对下面几 ...

  6. Hibernate通过自编写sql查询

    public List<InterProductMsg> selectIsHaveProductid(String productId) { String sql="SELECT ...

  7. form表单序列化数据之后,追加额外数据

    form表单序列化数据之后追加额外数据多使用在js中,下面是追加额外数据的代码: <span style="font-size:18px;">$.param({'inv ...

  8. C#操作Excel报错:服务器出现意外情况。

    C#操作Excel表格时,如遇以下错误: 服务器出现意外情况.(异常来自 HRESULT:0x80010105(RPC_E_SERVERFAULT)) 解决方案: 打开你电脑中的Office-Exce ...

  9. C#中正则表达式的构建与匹配

    使用方法 [1]用用命名空间System.Text.RegularExpressions [2]构造正则表达式 在使用正则表达式时,要先构造正则表达式,这就用到了Regex类,其构建方式有两种: 基本 ...

  10. Oracle入门基础(1)

    1.数据库系统和数据管理系统的区别? 数据库系统=数据库的管理系统+oper操作员+硬件 2.Oracle的版本   8i /9i   10g/11g   12c(cloud) 3.Oracle主要组 ...