zoukankan      html  css  js  c++  java
  • bzoj3882 [Wc2015]K小割

    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$跑最小割,求出最小的最小割,然后加上这个最小割就行了。
    不过细节巨多,所以我基本上是抄的代码。。
     
      1 //It is made by wfj_2048~
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <cstdio>
      7 #include <vector>
      8 #include <cmath>
      9 #include <queue>
     10 #include <stack>
     11 #include <map>
     12 #include <set>
     13 #define inf (1<<28)
     14 #define il inline
     15 #define RG register
     16 #define ll long long
     17 
     18 using namespace std;
     19 
     20 struct E{ int u,v,w; }G[500010];
     21 
     22 int n,m,k,S,T,mx;
     23 
     24 il int gi(){
     25     RG int x=0,q=1; RG char ch=getchar();
     26     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
     27     if (ch=='-') q=-1,ch=getchar();
     28     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
     29     return q*x;
     30 }
     31 
     32 namespace brute{
     33     
     34     struct edge{ int nt,to; }g[22];
     35     
     36     int head[12],vi[12],vis[22],top,num;
     37     ll st[2000010];
     38     
     39     il void insert(RG int from,RG int to){
     40     g[++num]=(edge){head[from],to},head[from]=num; return;
     41     }
     42     
     43     il int find(RG int x,RG int T){
     44     if (x==T) return 1; vi[x]=1; RG int v;
     45     for (RG int i=head[x];i;i=g[i].nt){
     46         v=g[i].to; if (vi[v]) continue;
     47         if (find(v,T)) return 1;
     48     }
     49     return 0;
     50     }
     51     
     52     il int check(){
     53     memset(head,0,sizeof(head)),num=0;
     54     for (RG int i=1;i<=m;++i)
     55         if (!vis[i]) insert(G[i].u,G[i].v);
     56     memset(vi,0,sizeof(vi)); return !find(S,T);
     57     }
     58     
     59     il void dfs(RG int x,RG ll tot){
     60     if (x>m){
     61         if (check()) st[++top]=tot;
     62         return;
     63     }
     64     vis[x]=1,dfs(x+1,tot+G[x].w);
     65     vis[x]=0,dfs(x+1,tot); return;
     66     }
     67     
     68     int main(){
     69     dfs(1,0),sort(st+1,st+top+1);
     70     for (RG int i=1;i<=top && i<=k;++i) printf("%lld
    ",st[i]);
     71     if (top<k) puts("-1"); return 0;
     72     }
     73     
     74 }
     75 
     76 namespace heap{
     77     
     78     struct data{
     79     ll val; int i,level;
     80     il bool operator < (const data &a) const{ return val>a.val; }
     81     };
     82     
     83     struct node{ ll a,b; }e[200010];
     84     
     85     priority_queue <data> Q;
     86     
     87     ll mincut;
     88     
     89     il int cmp(const node &x,const node &y){
     90     if (x.a==y.a) return x.b<y.b; return x.a<y.a;
     91     }
     92     
     93     int main(){
     94     for (RG int i=1,x;i<=m;++i){
     95         x=G[i].u; if (x==S || x==T) x=G[i].v;
     96         if (!e[x].a) e[x].a=G[i].w; else{
     97         e[x].b=G[i].w;
     98         if (e[x].a<e[x].b) swap(e[x].a,e[x].b);
     99         mincut+=e[x].b,e[x].a-=e[x].b;
    100         }
    101     }
    102     if (T==n) e[S]=e[n-1],e[T]=e[n]; else e[S]=e[n],e[T]=e[n-1];
    103     n-=2,--k,sort(e+1,e+n+1,cmp),printf("%lld
    ",mincut);
    104     Q.push((data){mincut+e[1].a,1,1});
    105     for (;k && !Q.empty();--k){
    106         RG data x=Q.top(),tmp; Q.pop();
    107         printf("%lld
    ",x.val);
    108         if (x.level<2){
    109         tmp.val=x.val+e[x.i].b;
    110         tmp.i=x.i,tmp.level=x.level+1,Q.push(tmp);
    111         }
    112         if (x.i<n && x.level==1){
    113         tmp.val=x.val-e[x.i].a+e[x.i+1].a;
    114         tmp.i=x.i+1,tmp.level=1,Q.push(tmp);
    115         }
    116         if(x.i<n){
    117         tmp.val=x.val+e[x.i+1].a;
    118         tmp.i=x.i+1,tmp.level=1,Q.push(tmp);
    119         }
    120     }
    121     if (k) puts("-1"); return 0;
    122     }
    123     
    124 }
    125 
    126 namespace kthcut{
    127 
    128 #define M (3005)
    129 #define N (60)
    130     
    131     int head[N],cur[N],havs[N],havt[N],ds[N],dt[N],d[N],vis[N],in[M],q[10*M],num=1;
    132     
    133     struct Graph{
    134      
    135     struct edge{ int nt,to,flow,cap; }g[M];
    136     
    137     il void insert(RG int from,RG int to,RG int cap){
    138         g[++num]=(edge){head[from],to,0,cap},head[from]=num; return;
    139     }
    140     
    141     il int bfs(RG int S,RG int T){
    142         memset(d,0,sizeof(d)),d[S]=1;
    143         RG int h=0,t=1; q[t]=S;
    144         while (h<t){
    145         RG int x=q[++h],v;
    146         for (RG int i=head[x];i;i=g[i].nt){
    147             v=g[i].to;
    148             if (!d[v] && g[i].cap>g[i].flow){
    149             d[v]=d[x]+1,q[++t]=v;
    150             if (v==T) return 1;
    151             }
    152         }
    153         }
    154         return d[T];
    155     }
    156     
    157     il ll dfs(RG int x,RG int T,RG int a){
    158         if (!a || x==T) return a; RG ll flow=0,f;
    159         for (RG int &i=cur[x],v;i;i=g[i].nt){
    160         v=g[i].to;
    161         if (d[v]==d[x]+1 && g[i].cap>g[i].flow){
    162             f=dfs(v,T,min(a,g[i].cap-g[i].flow));
    163             if (!f){ d[v]=0; continue; }
    164             g[i].flow+=f,g[i^1].flow-=f;
    165             flow+=f,a-=f; if (!a) return flow;
    166         }
    167         }
    168         return flow;
    169     }
    170     
    171     il ll mincut(RG int S,RG int T){
    172         RG ll cut=0;
    173         while (bfs(S,T)){
    174         memcpy(cur,head,sizeof(head));
    175         cut+=dfs(S,T,inf); if (cut>inf) return cut;
    176         }
    177         return cut;
    178     }
    179     
    180     il void DFS(RG int x){
    181         vis[x]=1;
    182         for (RG int i=head[x];i;i=g[i].nt)
    183         if (g[i].cap>g[i].flow && !vis[g[i].to]) DFS(g[i].to);
    184         return;
    185     }
    186     
    187     il void getcut(){
    188         memset(vis,0,sizeof(vis)),memset(in,0,sizeof(in)),DFS(S);
    189         for (RG int i=1;i<=m;++i) if (vis[G[i].u] && !vis[G[i].v]) in[i]=1;
    190         return;
    191     }
    192     
    193     }Gra,lin1,lin2;
    194     
    195     struct node{
    196     
    197     int must[M],stop[M],id,ww; ll val;
    198     
    199     il bool operator < (const node &a) const{ return val>a.val; }
    200     
    201     il void build(){
    202         val=0,lin1=Gra;
    203         for (RG int i=1;i<=m;++i)
    204         if (must[i]) val+=G[i].w,lin1.g[i<<1].cap=0;
    205         else if (stop[i]) lin1.g[i<<1].cap=inf;
    206         val+=lin1.mincut(S,T),lin1.getcut(),ww=inf,id=0;
    207         memset(havs,0,sizeof(havs)),memset(havt,0,sizeof(havt));
    208         for (RG int i=1;i<=m;++i){
    209         if (must[i] || stop[i]) continue;
    210         if (in[i]){
    211             if (!havs[G[i].u]){
    212             havs[G[i].u]=1,lin2=lin1;
    213             ds[G[i].u]=lin2.mincut(S,G[i].u);
    214             }
    215             if (!havt[G[i].v]){
    216             havt[G[i].v]=1,lin2=lin1;
    217             dt[G[i].v]=lin2.mincut(G[i].v,T);
    218             }
    219             if (ds[G[i].u]<ww) ww=ds[G[i].u],id=i;
    220             if (dt[G[i].v]<ww) ww=dt[G[i].v],id=i;
    221         } else if (G[i].w<ww) ww=G[i].w,id=i;
    222         }
    223         val+=ww; return;
    224     }
    225     
    226     }a,b;
    227     
    228     priority_queue <node> Q;
    229     
    230     int main(){
    231     for (RG int i=1;i<=m;++i){
    232         Gra.insert(G[i].u,G[i].v,G[i].w);
    233         Gra.insert(G[i].v,G[i].u,0);
    234     }
    235     --k,lin1=Gra,printf("%lld
    ",lin1.mincut(S,T));
    236     a.build(); if (a.val<inf) Q.push(a);
    237     for (;k && !Q.empty();--k){
    238         a=b=Q.top(),Q.pop(),printf("%lld
    ",a.val);
    239         a.must[a.id]=1,a.build(); if (a.val<inf) Q.push(a);
    240         b.stop[b.id]=1,b.build(); if (b.val<inf) Q.push(b);
    241     }
    242     if (k) puts("-1"); return 0;
    243     }
    244          
    245 }
    246 
    247 int main(){
    248 #ifndef ONLINE_JUDGE
    249     freopen("kthcut.in","r",stdin);
    250     freopen("kthcut.out","w",stdout);
    251 #endif
    252     n=gi(),m=gi(),S=gi(),T=gi(),k=gi();
    253     for (RG int i=1;i<=m;++i)
    254     G[i].u=gi(),G[i].v=gi(),G[i].w=gi(),mx=max(mx,G[i].w);
    255     if (m<=20) brute::main();
    256     else if (n<=50 && k<=100 && mx<=65536) kthcut::main();
    257     else heap::main();
    258     return 0;
    259 }
  • 相关阅读:
    基于摸板匹配的目標跟蹤算法
    spoj 2713 Can you answer these queries IV
    zoj 3633 Alice's present
    hdu 3642 Get The Treasury
    poj 1195 Mobile phones
    poj 2760 End of Windless Days
    zoj 3540 Adding New Machine
    spoj 1716 Can you answer these queries III
    spoj 1043 Can you answer these queries I
    spoj 2916 Can you answer these queries V
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7223102.html
Copyright © 2011-2022 走看看