四连测Day4

题解和题目看这里

#include<bits/stdc++.h>
#define ll long long
#define mod 998244353
using namespace std;
ll dp[1010][1010],ans[1010];
int spc[1010],fir[2020],to[2020],nxt[2020],cnt;
inline void link(int u,int v) {
    nxt[++cnt]=fir[u];
    fir[u]=cnt;
    to[cnt]=v;
}
inline int dfs(int x,int fa) {
    int i,j,k,t,s=spc[x];
    dp[x][spc[x]]=1;
    ans[spc[x]]++;
    for (i=fir[x]; i; i=nxt[i]) {
        if (to[i]==fa) continue;
        int t=dfs(to[i],x);
        for (j=s; j>=spc[x]; j--) for (k=t; k>=0; k--) {
                ans[j+k]+=dp[to[i]][k]*dp[x][j];
                dp[x][j+k]+=dp[to[i]][k]*dp[x][j];
                ans[j+k]%=mod;
                dp[x][j+k]%=mod;
            }
        s+=t;
    }
    return s;
}
int main() {
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
    int n,m,u,v,i;
    scanf("%d%d",&n,&m);
    for (i=0; i<m; i++) scanf("%d",&u),spc[u]=1;
    for (i=1; i<n; i++) {
        scanf("%d%d",&u,&v);
        link(u,v);
        link(v,u);
    }
    dfs(1,0);
    for (i=0; i<=m; i++) printf("%d ",ans[i]);
} 
tree
#include<bits/stdc++.h>
using namespace std;
int S,T;
int cnt=1,fst[410],nxt[1010],to[1010],fl[1010],va[1010];
void link(int u,int v,int f,int c) {
    nxt[++cnt]=fst[u];
    fst[u]=cnt;
    to[cnt]=v;
    fl[cnt]=f;
    va[cnt]=c;
}
int q[410],head,tail;
int n,m;
int k;
int ans;
int vis[410],pre[410],dis[410];
int spfa() {
    memset(vis,0,sizeof(vis));
    memset(pre,0,sizeof(pre));
    memset(dis,127,sizeof(dis));
    head=tail=0;
    q[tail++]=S;
    dis[S]=0;
    while(head<tail) {
        int x=q[head++];
        for(int i=fst[x]; i; i=nxt[i]) {
            if(fl[i]==0) continue;
            if(dis[to[i]]>dis[x]+va[i]) {
                dis[to[i]]=dis[x]+va[i];
                pre[to[i]]=i^1;
                if(!vis[to[i]]) {
                    vis[to[i]]=1;
                    q[tail++]=to[i];
                }
            }
        }
        vis[x]=0;
    }
    return pre[T]==0?0:1;
}
void EK() {
    int minx=2147483233;
    int sumx=0;
    for(int i=T; i!=S; i=to[pre[i]]) {
        minx=min(minx,fl[pre[i]^1]);
        sumx+=va[pre[i]^1];
    }
    ans+=-minx*sumx;
    for(int i=T; i!=S; i=to[pre[i]]) {
        fl[pre[i]^1]-=minx;
        fl[pre[i]]+=minx;
    }
}
int WoRk() {
    while(spfa()) EK();
    return ans;
}
int main() {
    freopen("robot.in","r",stdin);
    freopen("robot.out","w",stdout);
    scanf("%d%d",&n,&m);
    S=n+m+1;
    T=n+m+2;
    for(int i=1; i<=n; i++) {
        scanf("%d",&k);
        link(S,i,k,0);
        link(i,S,0,0);
    }
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            scanf("%d",&k);
            link(i,n+j,1,-k);
            link(n+j,i,0,k);
        }
    }
    for(int i=1; i<=m; i++) {
        link(i+n,T,1,0);
        link(T,i+n,0,0);
    }
    printf("%d\n",WoRk());
}
robot(辣鸡EK还我AK)
#include<bits/stdc++.h>
using namespace std;
int S,T;
int cnt=1,fst[410],nxt[1010],to[1010],fl[1010],va[1010];
void link(int u,int v,int f,int c) {
    nxt[++cnt]=fst[u];
    fst[u]=cnt;
    to[cnt]=v;
    fl[cnt]=f;
    va[cnt]=c;
}
int q[410],head,tail;
int n,m;
int k;
int ans;
int vis[410],dis[410];
int spfa() {
    memset(vis,0,sizeof(vis));
    memset(dis,127,sizeof(dis));
    head=tail=0;
    q[tail++]=T;
    dis[T]=0;
    while(head<tail) {
        int x=q[head++];
        for(int i=fst[x]; i; i=nxt[i]) {
            if(fl[i^1]==0) continue;
            if(dis[to[i]]>dis[x]+va[i^1]) {
                dis[to[i]]=dis[x]+va[i^1];
                if(!vis[to[i]]) {
                    vis[to[i]]=1;
                    q[tail++]=to[i];
                }
            }
        }
        vis[x]=0;
    }
    return dis[S]==dis[0]?0:1;
}
int ZKW(int x,int a) {
    if(x==T||!a) {
        ans+=dis[S]*a;
        return a;
    }
    if(vis[x]) return 0;
    vis[x]=1;
    int res=0,f;
    for(int i=fst[x]; i&&a; i=nxt[i])
        if(dis[to[i]]==dis[x]-va[i]&&(f=ZKW(to[i],min(a,fl[i]))))
            res+=f,fl[i]-=f,fl[i^1]+=f,a-=f;
    vis[x]=0;
    return res;
}
void WoRk() {
    while(spfa()) ZKW(S,2147483233);
}
int main() {
    freopen("robot.in","r",stdin);
    freopen("robot.out","w",stdout);
    scanf("%d%d",&n,&m);
    S=n+m+1;
    T=n+m+2;
    for(int i=1; i<=n; i++) {
        scanf("%d",&k);
        link(S,i,k,0);
        link(i,S,0,0);
    }
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            scanf("%d",&k);
            link(i,n+j,1,-k);
            link(n+j,i,0,k);
        }
    }
    for(int i=1; i<=m; i++) {
        link(i+n,T,1,0);
        link(T,i+n,0,0);
    }
    WoRk();
    printf("%d\n",-ans);
}
robot(ZKW大法好)
#include<bits/stdc++.h>
using namespace std;
namespace Seg_Tree {
#define lx (x<<1)
#define rx (x<<1|1)
    int c[4*1000010];
    int sum[4*1000010];
    void update(int x) {
        c[x]=c[lx]+c[rx];
        sum[x]=sum[lx]+sum[rx];
    }
    void insrt(int x,int l,int r,int p) {
        if(l==r) {
            c[x]++;
            sum[x]+=p;
            return;
        }
        int mid=(l+r)>>1;
        if(p<=mid) insrt(lx,l,mid,p);
        else insrt(rx,mid+1,r,p);
        update(x);
    }
    void del(int x,int l,int r,int p) {
        if(l==r) {
            c[x]--;
            sum[x]-=p;
            return;
        }
        int mid=(l+r)>>1;
        if(p<=mid) del(lx,l,mid,p);
        else del(rx,mid+1,r,p);
        update(x);
    }
    int qury(int x,int l,int r,int p) {
        if(l==r) return l;
        int mid=(l+r)>>1;
        if(c[lx]>=p) return qury(lx,l,mid,p);
        else return qury(rx,mid+1,r,p-c[lx]);
    }
    int Qury(int x,int l,int r,int p) {
        if(r==p) return sum[x];
        int mid=(l+r)>>1;
        if(p<=mid) return Qury(lx,l,mid,p);
        else return sum[lx]+Qury(rx,mid+1,r,p);
    }
}
using namespace Seg_Tree;
int n,m;
int A[100010];
int check(int l,int r) {
    int mid=(r-l+2)/2;
    int mi=qury(1,1,1000000,mid);
    int sum1=Qury(1,1,1000000,mi);
    int sum2=Qury(1,1,1000000,1000000);
    if(mid*mi-sum1+sum2-sum1-(r-l+1-mid)*mi>m) return 0;
    return 1;
}
int main() {
    freopen("choose.in","r",stdin);
    freopen("choose.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++) scanf("%d",&A[i]);
    int r=1,ans=0;
    insrt(1,1,1000000,A[r]);
    for(int l=1; l<=n; l++) {
        if(l>1)del(1,1,1000000,A[l-1]);
        while(check(l,r)) {
            r++;
            if(r>n) break;
            insrt(1,1,1000000,A[r]);
        }
        ans=max(ans,r-l);
    }
    cout<<ans<<endl;
}
choose

 

转载于:https://www.cnblogs.com/wjxgy/p/9455200.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值