• HDU-4370 0 or 1( 最短路 )


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4370

    Problem Description
    Given a n*n matrix Cij (1<=i,j<=n),We want to find a n*n matrix Xij (1<=i,j<=n),which is 0 or 1.

    Besides,Xij meets the following conditions:

    1.X12+X13+...X1n=1
    2.X1n+X2n+...Xn-1n=1
    3.for each i (1<i<n), satisfies ∑Xki (1<=k<=n)=∑Xij (1<=j<=n).

    For example, if n=4,we can get the following equality:

    X12+X13+X14=1
    X14+X24+X34=1
    X12+X22+X32+X42=X21+X22+X23+X24
    X13+X23+X33+X43=X31+X32+X33+X34

    Now ,we want to know the minimum of ∑Cij*Xij(1<=i,j<=n) you can get.
    Hint

    For sample, X12=X24=1,all other Xij is 0.
     
    Input
    The input consists of multiple test cases (less than 35 case).
    For each test case ,the first line contains one integer n (1<n<=300).
    The next n lines, for each lines, each of which contains n integers, illustrating the matrix C, The j-th integer on i-th line is Cij(0<=Cij<=100000).
     
    Output
    For each case, output the minimum of ∑Cij*Xij you can get.
     
    Sample Input
    4
    1 2 4 10
    2 0 1 1
    2 2 0 5
    6 3 1 2
     
    Sample Output
    3
     
    转换思维的一道题,虽然是在最短路的专题里看见的,但是一开始真想不到是最短路,还以为是一个求min( c[1][n], c[1][k] + c[k][n] )( 1 < k < n )的水题,不过认真看完题解发现转换思维之后确实是一道水题,难就难在转换思维
    理解条件之前先转换一下思维,将矩阵C看做描述N个点花费的邻接矩阵
    再来看三个条件:
    条件一:表示1号点出度为1
    条件二:表示n号点入度为1
    条件三:表示k( 1 < k < n )号点出度等于入度
    最后再来看看题目要求,∑Cij*Xij(1<=i,j<=n),很明显,这是某个路径的花费,而路径的含义可以有以下两种:
    一:1号点到n号点的花费
    二:1号点经过其它点成环,n号点经过其它点成环,这两个环的花费之和
    于是,就变成了一道简单的最短路问题
    关于环花费的算法,可以改进spfa算法,初始化dis[start] = INF,且一开始让源点之外的点入队
    代码如下
     
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<map>
     6 #include<cstdio>
     7 #include<queue>
     8 #include<stack>
     9 
    10 using namespace std;
    11 
    12 const int INF = 0x3f3f3f3f;
    13 
    14 int cost[305][305];
    15 int dis[305];
    16 int n;
    17 bool vis[305];
    18 
    19 void spfa( int start ){
    20     stack<int> Q;
    21 
    22     for( int i = 1; i <= n; i++ ){
    23         dis[i] = cost[start][i];
    24         if( i != start ){
    25             Q.push( i );
    26             vis[i] = true;
    27         }
    28         else{
    29             vis[i] = false;
    30         }
    31     }
    32     dis[start] = INF;
    33 
    34     while( !Q.empty() ){
    35         int x = Q.top(); Q.pop(); vis[x] = false;
    36 
    37         for( int y = 1; y <= n; y++ ){
    38             if( x == y ) continue;
    39             if( dis[x] + cost[x][y] < dis[y] ){
    40                 dis[y] = dis[x] + cost[x][y];
    41                 if( !vis[y] ){
    42                     vis[y] = true;
    43                     Q.push( y );
    44                 }
    45             }
    46         }
    47     }
    48 }
    49 
    50 int main(){
    51     ios::sync_with_stdio( false );
    52 
    53     while( cin >> n ){
    54         for( int i = 1; i <= n; i++ ){
    55             for( int j = 1; j <= n; j++ ){
    56                 cin >> cost[i][j];
    57             }
    58         }
    59 
    60         int ans, c1, cn;
    61         spfa( 1 );
    62         ans = dis[n];
    63         c1 = dis[1];
    64         spfa( n );
    65         cn = dis[n];
    66 
    67 
    68         cout << min( ans, c1 + cn ) << endl;
    69     }
    70 
    71     return 0;
    72 }

    将矩阵C看做描述N个点花费的邻接矩阵

  • 相关阅读:
    在SQL SERVER 2005中还原数据库时出现错误:system.data.sqlclient.sqlerror 媒体集有 2 个媒体簇 但只提供了 1 个。必须提供所有成员。 (microsoft.sqlserver.smo)
    Mysql的Root密码忘记,查看或修改的解决方法
    Win7系统如何设置FTP详细过程
    该设备或资源(127.0.0.1)未设置为接受端口“16823”上的连接。
    window7防火墙无法更改某些设置,错误代码0×80070422
    访问FTP站点下载文件,提示“当前的安全设置不允许从该位置下载文件”的解决方案
    解决SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问的方法
    按状态选择链接元素
    类选择器与ID选择器的比较
    关于创建Web图像时应记住的五个要素
  • 原文地址:https://www.cnblogs.com/hollowstory/p/5670128.html
Copyright © 2020-2023  润新知