码迷,mamicode.com
首页 > 其他好文 > 详细

[TJOI 2015] 线性代数

时间:2018-08-29 21:26:33      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:end   tps   for   最大   ESS   pre   struct   signed   输出   

题目传送-Luogu3973

题意:

给定一个\(n×n\)的矩阵\(B\)和一个\(1×n\)的矩阵\(C\),求一个\(1×n\)\(01\)矩阵\(A\)。使得\(D=(A×B-C)×A^{\sf T}\)最大,其中\(A^{\sf T}\)\(A\)的转置。输出\(D\)
\(n \le 500,1 \le Allelement \le 1000\)

题解:

emmm这是道网络流..二十多万条边跑网络流也是有信仰的了
脑补一下我们可以发现以下性质:
只有当\(a_i=1\)\(a_j=1\)时,\(B_{i,j}\)才能被算贡献
也就意味着必须要选上\(c_i\)\(c_j\)的代价才能有\(B_{i,j}\)的贡献
这东西就和这题等价啦link

过程:

我:500*500=25000

代码:

const int N=510,M=250010;
int n,m;
int p[N];
struct PEO {
    int a,b,v;
    inline void in() {
        read(a); read(b); read(v);
    }
}a[M];
namespace FLOW {
    const int ALL=N+M,EDGE=(N+M*3)<<1;
    int S,T;
    int head[ALL],nxt[EDGE],to[EDGE],cap[EDGE],lst=1;
    inline void adde(int x,int y,int c) {
        nxt[++lst]=head[x]; to[lst]=y; cap[lst]=c; head[x]=lst;
    }
    inline void con(int x,int y,int c) {
        adde(x,y,c); adde(y,x,0);
    }
    int stp[ALL];
    inline bool bfs(int S) {
        queue<int> que; mem(stp,63);
        que.push(S); stp[S]=0; 
        while(!que.empty()) {
            int u=que.front(); que.pop();
            for(int i=head[u];i;i=nxt[i]) {
                int v=to[i];
                if(cap[i] && stp[v]>stp[u]+1) {
                    stp[v]=stp[u]+1;
                    que.push(v);
                }
            }
        }
        return stp[T]!=stp[0];
    }
    int cur[ALL];
    inline int dfs(int u,int f) {
        if(!f || u==T) return f;
        for(int &i=cur[u];i;i=nxt[i]) {
            int v=to[i];
            if(stp[v]==stp[u]+1 && cap[i]) {
                int flow=dfs(v,min(f,cap[i]));
                if(flow) {
                    cap[i]-=flow; cap[i^1]+=flow;
                    return flow;
                }
            }
        }
        return 0;
    }
    inline int Dinic() {
        int Flow=0,add=0;
        while(bfs(S)) {

            memcpy(cur,head,sizeof(head));
            do {add=dfs(S,INF); Flow+=add;} while(add);
        }
        return Flow;
    }
    inline void Construct() {
        S=n+m+1; T=S+1;
        for(int i=1;i<=n;i++) {
            con(S,i,p[i]);
        }
        for(int i=1;i<=m;i++) {
            con(a[i].a,i+n,INF);
            con(a[i].b,i+n,INF);
            con(i+n,T,a[i].v);
        }
    }
    inline int main() {
        Construct();
        // printf("%lld %lld %lld %lld\n",S,T,lst,EDGE);
        return Dinic();
    }
}
int sum=0;
signed main() {
    read(n); m=n*n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) {
            int p=(i-1)*n+j;
            a[p].a=i; a[p].b=j; read(a[p].v);
            sum+=a[p].v;
        }
    for(int i=1;i<=n;i++) read(p[i]);
    int ans=FLOW::main();
    printf("%d\n",sum-ans);
    return 0;
}

用时:5min(用模板)

[TJOI 2015] 线性代数

标签:end   tps   for   最大   ESS   pre   struct   signed   输出   

原文地址:https://www.cnblogs.com/functionendless/p/9556689.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!