• cf786E ALT (最小割+倍增优化建图)


    如果把“我全都要”看作是我全不要的话,就可以用最小割解决啦

    源点S,汇点T

    我们试图让每个市民作为一个等待被割断的路径

    把狗狗给市民:建边(S,i,1),其中i是市民

    把狗狗给守卫:建边(j,T,1),其中j是守卫(也就是边)

    市民要在路上所有边看到狗:建边(i,j,1),其中i是市民,j是i经过的边

    (众所周知,(!A)&(!B)==!(A|B),所以要把两种选择串起来)

    然而这样边数太多了,考虑倍增来优化建边

    ...反正就是倍增优化建边,流量给正无穷

    最大流=最小割,跑个dinic就行了(要加当前弧优化不然会T)

    然后考虑输出方案。一个边如果被割断了,那么它的残余容量就是0

    所以我们来从Sdfs一下,如果能搜到某个人,说明他没有狗;如果能搜到某条边,又因为S和T不连通,说明这条边到T要被割断,说明它有狗

    各种各样的数组开大一点又不会怀孕

      1 #include<bits/stdc++.h>
      2 #define pa pair<int,int>
      3 #define CLR(a,x) memset(a,x,sizeof(a))
      4 using namespace std;
      5 typedef long long ll;
      6 const int maxn=2e4+10,inf=0x3f3f3f3f;
      7 
      8 inline ll rd(){
      9     ll x=0;char c=getchar();int neg=1;
     10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
     11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     12     return x*neg;
     13 }
     14 
     15 struct Edge{
     16     int b,l,ne;
     17 }ek[maxn*100];
     18 int N,M,ekh[maxn*50],kct=1;
     19 int egh[maxn],eg[maxn*2][2],ect=1;
     20 int dep[maxn*40],fa[maxn][20],id[maxn][20],pct=2;
     21 int S=1,T=2,P[maxn];
     22 int A[maxn],cur[maxn*40];
     23 bool flag[maxn*40],B[maxn];
     24 queue<int> q;
     25 
     26 inline void adeg(int a,int b){
     27     eg[++ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect;
     28 }
     29 inline void adek(int a,int b,int c){
     30     // printf("!%d %d %d
    ",a,b,c);
     31     ek[++kct].b=b,ek[kct].l=c,ek[kct].ne=ekh[a],ekh[a]=kct; 
     32     ek[++kct].b=a,ek[kct].l=0,ek[kct].ne=ekh[b],ekh[b]=kct; 
     33 }
     34 
     35 void dfs(int x){
     36     for(int i=0;fa[x][i]&&fa[fa[x][i]][i];i++){
     37         fa[x][i+1]=fa[fa[x][i]][i];
     38         id[x][i+1]=++pct;
     39         adek(id[x][i+1],id[x][i],inf);
     40         adek(id[x][i+1],id[fa[x][i]][i],inf);
     41     }
     42     for(int i=egh[x];i;i=eg[i][1]){
     43         int b=eg[i][0];
     44         if(b==fa[x][0]) continue;
     45         fa[b][0]=x;dep[b]=dep[x]+1;
     46         id[b][0]=++pct;adek(id[b][0],T,1);
     47         // printf("~%d %d
    ",b,id[b][0]);
     48         dfs(b);
     49     }
     50 }
     51 
     52 void buildlca(int x,int y,int p){
     53     if(dep[x]<dep[y]) swap(x,y);
     54     for(int i=log2(dep[x]-dep[y]);i>=0&&dep[x]!=dep[y];i--){
     55         if(dep[fa[x][i]]>=dep[y]){
     56             adek(p,id[x][i],1);
     57             x=fa[x][i];
     58         }
     59     }
     60     if(x==y) return;
     61     for(int i=log2(dep[x]);i>=0;i--){
     62         if(fa[x][i]!=fa[y][i]){
     63             adek(p,id[x][i],1);adek(p,id[y][i],1);
     64             x=fa[x][i],y=fa[y][i];
     65         }
     66     }
     67     adek(p,id[x][0],1);adek(p,id[y][0],1);
     68         
     69 }
     70 
     71 bool bfs(){
     72     CLR(dep,0);CLR(cur,-1);
     73     dep[S]=1;q.push(S);
     74     while(!q.empty()){
     75         int p=q.front();q.pop();
     76         // printf("!@#%d %d
    ",p,dep[p]);
     77         for(int i=ekh[p];i;i=ek[i].ne){
     78             int b=ek[i].b;
     79             if(dep[b]||!ek[i].l) continue;
     80             dep[b]=dep[p]+1;
     81             q.push(b);
     82         }
     83     }
     84     return dep[T];
     85 }
     86  
     87 int dinic(int x,int y){
     88     if(x==T) return y;
     89     int tmp=y;
     90     if(cur[x]==-1) cur[x]=ekh[x];
     91     for(int &i=cur[x];i;i=ek[i].ne){
     92         // printf("%d %d
    ",i,cur[x]);
     93         int b=ek[i].b;
     94         if(dep[b]!=dep[x]+1||!ek[i].l) continue;
     95         int re=dinic(b,min(ek[i].l,tmp));
     96         ek[i].l-=re,ek[i^1].l+=re;
     97         tmp-=re;if(!tmp) break;
     98     }return y-tmp;
     99 }
    100 
    101 void getans(int x){
    102     flag[x]=1;
    103     for(int i=ekh[x];i;i=ek[i].ne){
    104         int b=ek[i].b;
    105         if(!ek[i].l) continue;
    106         if(!flag[b]) getans(b);
    107     }
    108 }
    109 
    110 int main(){
    111     // freopen("768E.in","r",stdin);
    112     int i,j,k;
    113     N=rd(),M=rd();
    114     for(i=1;i<N;i++){
    115         int a=rd(),b=rd();
    116         adeg(a,b);adeg(b,a);
    117     }
    118     for(i=1;i<=M;i++) P[i]=++pct;
    119     dep[1]=1;dfs(1);
    120     for(i=1;i<=M;i++){
    121         int a=rd(),b=rd();
    122         adek(S,P[i],1);
    123         buildlca(a,b,P[i]);
    124     }
    125     int ans=0,a=0,b=0;
    126     while(bfs()) ans+=dinic(S,inf);
    127     getans(S);
    128     for(i=3;i<=M+2;i++)
    129         if(!flag[i]) A[++a]=i-2;
    130     for(i=2;i<=N;i++)
    131         if(flag[id[i][0]]) B[i]=1,b++;
    132     printf("%d
    %d ",ans,a);
    133     for(i=1;i<=a;i++)
    134         printf("%d ",A[i]);
    135     printf("
    %d ",b);
    136     for(i=1;i<N;i++){
    137         int x=eg[i<<1][0],y=eg[i<<1|1][0];
    138         if(fa[x][0]!=y) swap(x,y);
    139         // printf("!%d %d!
    ",x,y);
    140         if(B[x]) printf("%d ",i);
    141     }
    142     
    143     return 0;
    144 }
  • 相关阅读:
    实用产品规划
    产品经理对用户的调研
    产品经理用户研究
    竞品分析方案
    产品竞品分析
    Mybatis Plus
    shiro
    Spring cloud
    Spring Boot
    Redis入门(二)
  • 原文地址:https://www.cnblogs.com/Ressed/p/9812925.html
Copyright © 2020-2023  润新知