HDU-4370 0 or 1( 最短路 )
2016-07-14 13:31
357 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4370
[align=left]Problem Description[/align]
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.
[align=left]Input[/align]
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).
[align=left]Output[/align]
For each case, output the minimum of ∑Cij*Xij you can get.
[align=left]Sample Input[/align]
4
1 2 4 10
2 0 1 1
2 2 0 5
6 3 1 2
[align=left]Sample Output[/align]
3
转换思维的一道题,虽然是在最短路的专题里看见的,但是一开始真想不到是最短路,还以为是一个求min( c[1]
, c[1][k] + c[k]
)( 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,且一开始让源点之外的点入队
代码如下
将矩阵C看做描述N个点花费的邻接矩阵
[align=left]Problem Description[/align]
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.
[align=left]Input[/align]
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).
[align=left]Output[/align]
For each case, output the minimum of ∑Cij*Xij you can get.
[align=left]Sample Input[/align]
4
1 2 4 10
2 0 1 1
2 2 0 5
6 3 1 2
[align=left]Sample Output[/align]
3
转换思维的一道题,虽然是在最短路的专题里看见的,但是一开始真想不到是最短路,还以为是一个求min( c[1]
, c[1][k] + c[k]
)( 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,且一开始让源点之外的点入队
代码如下
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<map> #include<cstdio> #include<queue> #include<stack> using namespace std; const int INF = 0x3f3f3f3f; int cost[305][305]; int dis[305]; int n; bool vis[305]; void spfa( int start ){ stack<int> Q; for( int i = 1; i <= n; i++ ){ dis[i] = cost[start][i]; if( i != start ){ Q.push( i ); vis[i] = true; } else{ vis[i] = false; } } dis[start] = INF; while( !Q.empty() ){ int x = Q.top(); Q.pop(); vis[x] = false; for( int y = 1; y <= n; y++ ){ if( x == y ) continue; if( dis[x] + cost[x][y] < dis[y] ){ dis[y] = dis[x] + cost[x][y]; if( !vis[y] ){ vis[y] = true; Q.push( y ); } } } } } int main(){ ios::sync_with_stdio( false ); while( cin >> n ){ for( int i = 1; i <= n; i++ ){ for( int j = 1; j <= n; j++ ){ cin >> cost[i][j]; } } int ans, c1, cn; spfa( 1 ); ans = dis ; c1 = dis[1]; spfa( n ); cn = dis ; cout << min( ans, c1 + cn ) << endl; } return 0; }
将矩阵C看做描述N个点花费的邻接矩阵
相关文章推荐
- asp.net 如何引用dll
- PAT L2-002. 链表去重 模拟
- HTML <object> 标签
- Activiti基础教程--03(HelloWorld)
- OkHttp拦截器之获取Response.body的内容
- linux学习8:文件权限
- Java中JDBC常见对象
- 解决WebView加载本地文件乱码
- ORACLE分页查询
- 解决WebView加载本地文件乱码
- list 列表
- guess-number-higher-or-lower
- Selenium2 入门[3] —— 等待页面加载完毕
- 使用Spring配置ActiveMQ的发布订阅模式
- websocket 断线重连
- 算法和机器性能提高带来输入规模增大的比较
- Git入门
- iterm2 快捷键
- Description Resource Path Location Type Java compiler level does not match the version of the instal
- C++ 11 中的右值引用