• [TJOI 2015] 线性代数


    题目传送-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
    ",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
    ",sum-ans);
    	return 0;
    }
    

    用时:5min(用模板)

  • 相关阅读:
    [Leetcode]Linked List Cycle
    [Leetcode]Excel Sheet Column Number
    [Leetcode]Unique Binary Search Trees
    [Leetcode]Same Tree
    同时访问内外网设置路由信息
    希腊字母表示及读音
    jni入门
    查看某个进程运行时间的几种方法
    企业级hbase HA配置
    存在单点故障的namenode宕机恢复测试
  • 原文地址:https://www.cnblogs.com/functionendless/p/9556689.html
Copyright © 2020-2023  润新知