zoukankan      html  css  js  c++  java
  • BZOJ 3698: XWW的难题

    Description

    XWW是个影响力很大的人,他有很多的追随者。这些追随者都想要加入XWW教成为XWW的教徒。但是这并不容易,需要通过XWW的考核。
    XWW给你出了这么一个难题:XWW给你一个N × N的正实数矩阵A,满足XWW性。
    称一个N × N的矩阵满足XWW性当且仅当:(1)A[N][N]=0;(2)矩阵中每行的最后一个元素等于该行前N-1个数的和;(3)矩阵中每列的最后一个元素等于该列前N-1个数的和。
    现在你要给A中的数进行取整操作(可以是上取整或者下取整),使得最后的A矩阵仍然满足XWW性。同时XWW还要求A中的元素之和尽量大。

    Input

    第一行一个整数N,N ≤ 100。
    接下来N行每行包含N个绝对值小于等于1000的实数,最多一位小数。

    Output

    输出一行,即取整后A矩阵的元素之和的最大值。无解输出No。

    Sample Input

    4

    3.1 6.8 7.3 17.2

    9.6 2.4 0.7 12.7

    3.6 1.2 6.5 11.3

    16.3 10.4 14.5 0

    Sample Output
    129

    HINT

    【数据规模与约定】

    有10组数据,n的大小分别为10,20,30...100。

    【样例说明】

    样例中取整后满足XWW性的和最大的矩阵为:

    3 7 8 18

    10 3 0 13

    4 1 7 12

    17 11 15 0

    题解
    有源汇有上下界网络流 ,
    因为是可以向上或者是向下取整,那也就是说一个数他的变化范围是[(int)a[i][j] , (int)a[i][j]+1];
    从S向每一行连边 ,容量范围是[(int)a[i][n] , (int)a[i][n]+1];
    从每一列向T连边, 容量范围是[(int)a[n][i] , (int)a[n][i]+1];
    然后 第i行向第j列连[(int)a[i][j] , (int)a[i][j]+1] 的边
    对于 1.0 这种 x.0 的不用连边 , 但是要留出去下限(我居然直接略过了。。。)

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<set>
    #include<map>
    using namespace std;
    const int N = 1e4+100 , inf = 1e8;
    inline int read()
    {
        register int x = 0 , f = 0; register char c = getchar();
        while(c < '0' || c > '9') f |= c == '-' , c = getchar();
        while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0' , c = getchar();
        return f ? -x : x;
    }
    int n , S , T , s , t , cnt = 1 , sum;
    double a[120][120];
    int head[N] , b[120][120] , du[N] , d[N];
    struct edge{ int v , nex , c; } e[N<<4];
    inline void add(int u , int v , int c) { e[++cnt].v = v; e[cnt].nex = head[u]; e[cnt].c = c; head[u] = cnt; e[++cnt].v = u; e[cnt].nex = head[v]; e[cnt].c = 0; head[v] = cnt; return ; }
    queue<int> q;
    bool bfs()
    {
    	for(int i = 1 ; i <= T+2 ; ++i) d[i] = 0; q.push(S); d[S] = 1;
    	while(q.size())
    	{
    		int x = q.front(); q.pop();
    		for(int i = head[x] , v; i ; i = e[i].nex)
    		{
    			v = e[i].v; if(d[v] || e[i].c == 0) continue;
    			d[v] = d[x] + 1; q.push(v);
    		}
    	}
    	return d[T] != 0;
    }
    
    int dfs(int x , int flow)
    {
    	if(x == T || flow == 0) return flow;
    	int res = 0 , k;
    	for(int i = head[x] , v; i ; i = e[i].nex)
    	{
    		v = e[i].v;
    		if(d[v] == d[x] + 1 && e[i].c)
    		{
    			k = dfs(v , min(e[i].c , flow));
    			if(k) { e[i].c -= k; e[i^1].c += k; res += k; flow -= k; if(flow == 0) return res; }
    			else d[v] = 0;
    		}
    	}
    	return res;
    }
    
    int Dinic()
    {
    	int ans = 0;
    	while(bfs()) ans += dfs(S , inf);
    	return ans;
    }
    
    void solve()
    {
    	s = n*2+1; t = s+1; S = t+1; T = S+1;
    	for(int i = 1 ; i <= n ; ++i) for(int j = 1 ; j <= n ; ++j) b[i][j] = (int)a[i][j];
    	for(int i = 1 ; i < n ; ++i)
    	{
    		if(a[i][n] != b[i][n]) add(s , i , 1);
    		du[s] -= b[i][n]; du[i] += b[i][n]; // 相等 
    		if(a[n][i] != b[n][i]) add(i+n , t , 1);
    		du[i+n] -= b[n][i]; du[t] += b[n][i];
    	}
    	for(int i = 1 ; i < n ; ++i) for(int j = 1 ; j < n ; ++j) 
    	{
    		if(a[i][j] != b[i][j]) add(i , j+n , 1);
    		du[i] -= b[i][j]; du[j+n] += b[i][j];
    	}
    	for(int i = 1 ; i <= T ; ++i) if(du[i] > 0) add(S , i , du[i]) , sum += du[i]; else if(du[i] < 0) add(i , T , -du[i]);
    	add(t , s , inf);
    	int ans = Dinic();
    	if(ans != sum) puts("No");
    	else
    	{
    		S = s; T = t;
    		cout << Dinic() * 3 << '
    ';
    	}
    	return ;
    }
    
    int main()
    {
    	n = read();
    	for(int i = 1 ; i <= n ; ++i) for(int j = 1 ; j <= n ; ++j) scanf("%lf" , &a[i][j]);
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    时间相关
    mongodb数据库怎么迁移
    删除项目中所有的__pycache__ 文件
    获取请求参数
    Linux VIM python 自动补全插件:pydiction
    Linux的环境变量.bash_profile .bashrc profile文件
    Linux下查看CPU型号,内存大小,硬盘空间的命令(详解)
    python3的一些文件操作的脚手架
    Python time strptime()方法 时间操作
    我看《架构漫谈》——1
  • 原文地址:https://www.cnblogs.com/R-Q-R-Q/p/12332712.html
Copyright © 2011-2022 走看看