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. Linux 系统排错

    ##root用户密码的修改 重启时按上下键打断引导,按“e”进入内核引导 在linux16行删除至途中所示位置,并进行修改: 修改完毕后按“ctrl+x”启动 进入系统切换到真实环境,开始修改root ...

  2. MongoDB安装为windows服务

    MongoDB 下载 下载地址:http://www.mongodb.org/downloads 下载安装完成之后 第一步 创建D:\Program Files\mongodb\data 目录第二步 ...

  3. 使用spyder编译器单步调试python

    1.将需要进行单步调试的函数在脚本中进行调用(十分重要的一步).由于python是解释型语言,在进行单步调试的时候需要告诉系统你使用了这个函数,单步调试才会进入你所需要调式的函数.如下图所示,我们定义 ...

  4. java——如何通过class调用该类的方法并获得返回值?(反射)

    demo: public class T{ public static void main(String[] args) throws Exception{ //获得Person的Class对象 Cl ...

  5. c++ for_each( )学习

    for_each()事实上是個 function template,其实质如下  [effective STL item 41] template<typename InputIterator, ...

  6. 树莓派安装Raspbian系统以及相关配置(通过Windows)

    1.准备 树莓派3B+(E14) 一张内存卡 (至少16G) 一个读卡器 普通电脑显示器,键盘,鼠标 2.操作系统烧制(下面的操作都是在Windows中操作,通过读开启读取内存卡) Raspbian系 ...

  7. Windows常用IDE下载(含安装教程)

    电脑办公 电脑系统(U盘安装) PE系统 WIN7 WIN8 WIN10 XP 电脑系统(直接安装) WIN7 WIN8 WIN10 Office office2003 office2007 offi ...

  8. A. Yet Another Problem with Strings 分块 + hash

    http://codeforces.com/gym/101138/problem/A 感觉有一种套路就是总长度 <= 某一个数的这类题,大多可以分块 首先把集合串按长度分块,对于每一个询问串, ...

  9. 第8章 IO类

    8.1 IO类 iostream                    istream, wistream从流中读取数据 ostream, wostream iostream, wiostream读写 ...

  10. 019-MD5加密模板工具类

    1 MD5加密工具类 package ${enclosing_package}; import java.math.BigInteger; import java.security.MessageDi ...