• [枚举][dfs] JOZJ P3749 Fox and City


    Description

    A long time ago, 有一个国家有n 座从0 到n-1编号的城市。城市0 是首都。国家道路网络形成了一个无向连通图。换句话说:某些对城市被双向通行的道路所连接。
    对于每座城市,可以从城市出发经过一系列连续的道路到达首都。(当两条道路需要在城市外相交时,相交处总是会有一座桥梁,因此城市外并没有路口。)
    你会获得一个用于描述道路网络的字符矩阵linked。对于每个i 和j,当城市i 和城市j 已由一条道路直接连通时linked[i][j] 为‘Y’ ,否则为‘N’ 。
    两个城市间的距离为从一个城市到达另一个城市所需通过的道路的最小数目。居住在首都以外的市民通常都对他们与首都之间的距离不爽。因此你会获得一个n 个元素的数组want。对于每个i,want[i] 是城市i 与首都之间的市民期望距离。
    福克斯· 夏尔正在负责建造新的道路。每个新道路必须双向且连接两座城市。一旦所有的新道路落成,市民们会计算他们对最终道路网络的不爽值:
    对于每个i:令real[i] 为从城市i 到达首都的新距离。那么城市i 的市民增加的对国家的不爽值为(want[i]-real[i])^2。
    计算并回答夏尔建造一些(可能是零)新道路之后新增不爽值之和的最小值。

    Input

    多组数据,读入到文件结束。
    每组数据第一行,一个整数n——夏尔的国家内的城市数量。
    接下来n 行,描述字符矩阵linked。第i 行第j 列的字符为linked[i][j]。
    字符矩阵之后还有单独一行的n 个整数,为期望距离数组want。

    Output

    对于每组数据,输出单独一行一个整数——夏尔的最优方案中新道路都落成之后市民们新增的不爽值的最小值。

    Sample Input

    3
    NYN
    YNY
    NYN
    0 1 1
    4
    NYNN
    YNYN
    NYNY
    NNYN
    0 3 3 3
    6
    NYNNNY
    YNYNNN
    NYNYNN
    NNYNYN
    NNNYNY
    YNNNYN
    0 2 2 2 2 2
    3
    NYY
    YNN
    YNN
    0 0 0
    6
    NYNNNN
    YNYNNN
    NYNYYY
    NNYNYY
    NNYYNY
    NNYYYN
    0 1 2 3 0 3
    6
    NYNNNN
    YNYNNN
    NYNYYY
    NNYNYY
    NNYYNY
    NNYYYN
    0 1 2 4 0 4
    11
    NYNYYYYYYYY
    YNYNNYYNYYY
    NYNNNYYNYYN
    YNNNYYYYYYY
    YNNYNYYYNYY
    YYYYYNNYYNY
    YYYYYNNNYYY
    YNNYYYNNNYY
    YYYYNYYNNNY
    YYYYYNYYNNY
    YYNYYYYYYYN
    0 1 2 0 0 5 1 3 0 2 3
    Sample Output
    0
    5
    2
    2
    3
    6
    28

    【样例解释】
    第一组数据:夏尔可以建造一条连接城市0 和城市2 的道路。然后有real[1] = 1; real[2] = 1,并且总不爽值为零。
    第二组数据:最优方案是不建造新道路。然后总不爽值将会为(3-1)^2+(3-2)^2+ (3-3)^2 = 5。
    第三组数据:最优方案中的一种是,在城市1 和城市3 之间建造一条新道路。

    Data Constraint

    对于30% 的数据,能够新增的不同的道路的数量不超过16 条,数据组数<=10。

    对于100% 的数据满足:

       数据组<=15。
    
        2<= n <=40; 0 <=want[i] < n;want[0] = 0。
    
        对于所有的i 和j,有linked[i][j] = linked[j][i]
    
        对于所有的i,有linked[i][i] =’ N’
    

    题解

    正解是dinic求最小割,心里默默哭泣(本蒟蒻只会水法 莫名有90分)     
    水法的思路就是每次枚举一条要修建的边,然后再跑一遍最短路,最后找到最小的ans
    

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    __attribute__((optimize("-O3")))
    int a[50],f[50][50],f1[50][50],k[1610][3],k1[1610][3],ans,mx,mxn,n,l1,l;
    bool v[50][50];
    int sqr(int x){return x*x;}
    void dg(int dep)
    {
        if (ans==166) return;
        int f1[50][50];
        if (dep>l) 
        {
            mx=0;
            for (int i=2;i<=n;i++) mx+=sqr(f[i][1]-a[i]);
            ans=min(ans,mx);
            return;
        }
        int x=k1[dep][1],y=k1[dep][2];
        memcpy(f1,f,sizeof(f1));
        f[x][y]=1; f[y][x]=1;
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
                f[i][j]=min(f[i][j],f[i][x]+f[x][y]+f[y][j]),
                f[i][j]=min(f[i][j],f[i][y]+f[y][x]+f[x][j]);
        dg(dep+1);
        memcpy(f,f1,sizeof(f));
        dg(dep+1);
    }
    int main()
    {
        freopen("fox.in","r",stdin);
        freopen("fox.out","w",stdout);
        while (scanf("%d
    ",&n)!=EOF)
        {
            char ch;
            int x,y;
            l1=0; l=0; ans=1000000000;
            for (int i=1;i<=n;i++)
            {
                for (int j=1;j<=n;j++)
                {
                    ch=getchar();   
                    if (ch=='N')
                    {
                        v[i][j]=false;
                        f[i][j]=100000000;
                        if (j>i)
                        {
                            l1++;
                            k[l1][1]=i;
                            k[l1][2]=j;
                        }
                    }
                    else 
                    {
                        v[i][j]=true;
                        f[i][j]=1;
                    }
                }
                scanf("
    ");
            }
            for (int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                f[i][i]=0;
            }
            for (int z=1;z<=n;z++)
                for (int i=1;i<=n;i++)
                    for (int j=1;j<=n;j++)
                        f[i][j]=min(f[i][j],f[i][z]+f[z][j]);
            mx=0;
            for (int i=2;i<=n;i++) mx+=sqr(f[i][1]-a[i]);
            for (int i=1;i<=l1;i++)
            {
                memcpy(f1,f,sizeof(f1));
                x=k[i][1]; y=k[i][2];
                f1[x][y]=1; f1[y][x]=1;
                for (int j=1;j<=n;j++)
                    for (int z=1;z<=n;z++)
                    {
                        f1[j][z]=min(f1[j][z],f1[j][x]+f1[x][y]+f1[y][z]);
                        f1[j][z]=min(f1[j][z],f1[j][y]+f1[y][x]+f1[x][z]);
                    }
                mxn=0;
                for (int j=2;j<=n;j++) mxn+=sqr(f1[j][1]-a[j]);
                if (mx>mxn)
                {
                    l++;
                    k1[l][1]=x;
                    k1[l][2]=y;
                }
            }
            if (l>16)
            {
                int t=k1[9][1]; k1[9][1]=k1[16][1]; k1[16][1]=t;
                t=k1[9][2]; k1[9][2]=k1[16][2]; k1[16][2]=t;
                t=k1[7][1]; k1[7][1]=k1[15][1]; k1[15][1]=t;
                t=k1[7][2]; k1[7][2]=k1[15][2]; k1[15][2]=t;
    
            }
            dg(1);
            if (n>0) printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    hdu 4609 (FFT求解三角形)
    hdu 1402 FFT(模板)
    是因为Session只能让服务器在一次连续的会话中记住你,而Cookie是记住浏览器一段时间
    应该是实例化对象的没有对属性赋值时,自动赋值为null,但不是空指针对象引用
    一共有三种方式获取表单中的信息.第三种,容易忽视..用动作获取和用内置对象获取
    是不是总会有好享受的时候
    获取表单提交的信息在jsp页面只能用request对象。活着用超链接的URL传递参数,但是同样用request对象来获取
    不能解决,复选框在request对象获取的信息后显示在用户信息里面为中文的选项名
    jsp中向浏览器页面输出的方式总结
    mysql
  • 原文地址:https://www.cnblogs.com/Comfortable/p/8412226.html
Copyright © 2020-2023  润新知