Given a n*n matrix C ij (1<=i,j<=n),We want to find a n*n matrix X ij (1<=i,j<=n),which is 0 or 1.


Besides,X
ij meets the following conditions:



1.X
12+X
13+...X
1n=1

2.X
1n+X
2n+...X
n-1n=1

3.for each i (1<i<n), satisfies ∑X
ki (1<=k<=n)=∑X
ij (1<=j<=n).



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



X
12+X
13+X
14=1

X
14+X
24+X
34=1

X
12+X
22+X
32+X
42=X
21+X
22+X
23+X
24

X
13+X
23+X
33+X
43=X
31+X
32+X
33+X
34



Now ,we want to know the minimum of ∑C
ij*X
ij(1<=i,j<=n) you can get.

Hint

For sample, X
12=X
24=1,all other X
ij is 0.

InputThe 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 C
ij(0<=C
ij<=100000).OutputFor each case, output the minimum of ∑C
ij*X
ij 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

这道题大致一看一脸懵,仔细一看还是懵。。。。。。。。

题意:

这个条件的意思就是从1这个点只能到到其他点中的一个点,简单一点就是1号点的出度为1

那么这个是n号点,只不过这个是n号点的入度为1

第三个条件就是除了一号点和n号点,其他点的出度等于入度

这个X是题上给出的限制条件,我们要使我们选出来的路符合这两个条件

既然X的值只能为0或1,那么我们只需要求从1到n的最小花费就可以了

就是求出来从起点到终点的最小花费,这个样子我们把题目上面输入的数存在邻接矩阵里面直接拿来用,这个矩阵正好满足上面三个条件,所以这是一个结果

但是我们要考虑环的存在,即起点形成一个环,终点n形成一个环,这个样子其他点的出入度为0也满足题意,但是要保证他不是自环,即必须保证有两个点

上代码:

 1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<queue>
6 using namespace std;
7 const int INF=0x3f3f3f3f;
8 int w[305][305],d[305],dis[305];
9 queue<int>r;
10 void spay(int start,int ends)
11 {
12 memset(d,INF,sizeof(d));
13 memset(dis,0,sizeof(dis));
14 for(int i=1;i<=ends;++i)
15 {
16 if(i!=start)
17 {
18 dis[i]=1;
19 d[i]=w[start][i];
20 r.push(i);
21 }
22 else
23 {
24 d[i]=INF;
25 }
26 }
27 while(!r.empty())
28 {
29 int x=r.front();
30 r.pop();
31 dis[x]=0;
32 for(int i=1;i<=ends;++i)
33 {
34 if(d[i]>d[x]+w[x][i])
35 {
36 d[i]=d[x]+w[x][i];
37 if(!dis[i])
38 {
39 dis[i]=1;
40 r.push(i);
41 }
42 }
43 }
44 }
45 }
46 int main()
47 {
48 int n;
49 while(~scanf("%d",&n))
50 {
51 memset(w,0,sizeof(w));
52 for(int i=1;i<=n;++i)
53 {
54 for(int j=1;j<=n;++j)
55 scanf("%d",&w[i][j]);
56 }
57 int q1,q2;
58 spay(1,n);
59 q1=d[n];
60 q2=d[1];
61 spay(n,n);
62 q2+=d[n];
63 printf("%d\n",min(q1,q2));
64 }
65 return 0;
66 }

网搜的代码:

  1 /*
2 HDU 4370 0 or 1
3 转换思维的题啊,由一道让人不知如何下手的题,转换为了最短路
4 基本思路就是把矩阵看做一个图,图中有n个点,1号点出度为1,
5 n号点入度为1,其它点出度和入度相等,路径长度都是非负数,
6
7 等价于一条从1号节点到n号节点的路径,故Xij=1表示需要经
8 过边(i,j),代价为Cij。Xij=0表示不经过边(i,j)。注意到Cij非负
9 且题目要求总代价最小,因此最优答案的路径一定可以对应一条简单路径。
10
11 最终,我们直接读入边权的邻接矩阵,跑一次1到n的最短路即可,记最短路为path。
12
13 漏了如下的情况B:
14 从1出发,走一个环(至少经过1个点,即不能
15 是自环),回到1;从n出发,走一个环(同理),回到n。
16 也就是1和n点的出度和入度都为1,其它点的出度和入度为0.
17
18 由于边权非负,于是两个环对应着两个简单环。
19
20 因此我们可以从1出发,找一个最小花费环,记代价为c1,
21 再从n出发,找一个最小花费环,记代价为c2。
22 (只需在最短路算法更新权值时多加一条记录即可:if(i==S) cir=min(cir,dis[u]+g[u][i]))
23
24 故最终答案为min(path,c1+c2)
25 */
26 /*
27 本程序用SPFA来完成最短路。
28 但是由于要计算从出发点出发的闭环的路径长度。
29 所以要在普通SPFA的基础上做点变化。
30
31 就是把dist[start]设为INF。同时一开始并不是让出发点入队,而是让
32 出发点能够到达的点入队。
33 */
34 #include<stdio.h>
35 #include<iostream>
36 #include<string.h>
37 #include<algorithm>
38 using namespace std;
39
40 const int INF=0x3f3f3f3f;
41 const int MAXN=330;
42 int cost[MAXN][MAXN];//保存路径长度的邻接矩阵
43 int dist[MAXN];
44 int que[MAXN];//注意队列的循环利用,建成循环队列
45 bool vis[MAXN];//是否在队列中标记
46
47 void SPFA(int start,int n)
48 {
49 int front=0,rear=0;
50 for(int v=1;v<=n;v++)//初始化
51 {
52 if(v==start)//由于要找start的闭环,所以dist[start]设为INF,且不入队
53 {
54 dist[v]=INF;
55 vis[v]=false;
56 }
57 else if(cost[start][v]!=INF)
58 {
59 dist[v]=cost[start][v];
60 que[rear++]=v;
61 vis[v]=true;
62 }
63 else//即dist[start][v]==INF情况,对本题没有这种情况
64 {
65 dist[v]=INF;
66 vis[v]=false;
67 }
68 }
69
70 while(front!=rear)//注意这个条件是不等,因为是循环队列
71 {
72 int u=que[front++];
73 for(int v=1;v<=n;v++)
74 {
75 if(dist[v]>dist[u]+cost[u][v])
76 {
77 dist[v]=dist[u]+cost[u][v];
78 if(!vis[v])//不在队列
79 {
80 vis[v]=true;
81 que[rear++]=v;
82 if(rear>=MAXN) rear=0;//循环队列
83 }
84 }
85 }
86 vis[u]=false;
87 if(front>=MAXN)front=0;
88 }
89
90 }
91 int main()
92 {
93 //freopen("in.txt","r",stdin);
94 //freopen("out.txt","w",stdout);
95 int n;
96 while(scanf("%d",&n)!=EOF)
97 {
98 for(int i=1;i<=n;i++)
99 for(int j=1;j<=n;j++)
100 scanf("%d",&cost[i][j]);
101 SPFA(1,n);
102 int ans=dist[n];//1到n的最短路
103 int loop1=dist[1];//1的闭环长度
104 SPFA(n,n);
105 int loopn=dist[n];//n的闭环长度
106 ans=min(ans,loop1+loopn);
107 printf("%d\n",ans);
108 }
109 return 0;
110 }

R - 0 or 1(最短路)的更多相关文章

  1. 分层图 (可以选择K条路的权为0,求最短路)

    分层图可以处理从图中选取k条边使其边权变为0,求最短路 Description 在你的强力援助下,PCY 成功完成了之前的所有任务,他觉得,现在正是出去浪的大好时光.于是,他来到高速公路上,找到一辆摩 ...

  2. 为什么使彩色图变灰RGB的权重会固定(R:0.299 G:0.587 B:0.114)?

    人眼对绿色的敏感度最高,对红色的敏感度次之,对蓝色的敏感度最低,因此使用不同的权重将得到比较合理的灰度图像.根据实验和理论推导得出以下数值 R: 0.299. G:  0.587. B: 0.114.

  3. OpenCV 学习笔记(9)RGB转换成灰度图像的一个常用公式Gray = R*0.299 + G*0.587 + B*0.114

    https://blog.csdn.net/fly_wt/article/details/86432886 RGB转换成灰度图像的一个常用公式是:Gray = R*0.299 + G*0.587 + ...

  4. HDU4370 0 or 1 最短路

    分析: 1001  (已更新) 显然,题目给的是一个0/1规划模型.解题的关键在于如何看出这个模型的本质.3个条件明显在刻画未知数之间的关系,从图论的角度思考问题,容易得到下面3个结论:1.X12+X ...

  5. HDU 4370 0 or 1 (最短路)

    [题目链接](http://acm.hdu.edu.cn/showproblem.ph Problem Description Given a n/n matrix Cij (1<=i,j< ...

  6. 小明同学喜欢体育锻炼,他常常去操场上跑步。跑道是一个圆形,在本题中,我们认为跑道是一个半径为R的圆形,设圆心的坐标原点(0,0)。小明跑步的起点坐标为(R,0),他沿着圆形跑道跑步,而且一直沿着一个方向跑步。回到家后,他查看了自己的计步器,计步器显示他跑步的总路程为L。小明想知道自己结束跑步时的坐标,但是他忘记自己是沿着顺时针方向还是逆时针方向跑的了。他想知道在这两种情况下的答案分别是多少。

    include "stdafx.h" #include<iostream> #include<vector> #include<string> ...

  7. HDU-4370 '0 or 1' 最短路 要考虑连通性

    题目链接:https://cn.vjudge.net/problem/HDU-4370 题意 给一个矩阵C(nn),要我们找到一个矩阵X(nn),满足以下条件: X_{12}+X_{13}+...X_ ...

  8. HDU - 4370 0 or 1 最短路

    HDU - 4370 参考:https://www.cnblogs.com/hollowstory/p/5670128.html 题意: 给定一个矩阵C, 构造一个A矩阵,满足条件: 1.X12+X1 ...

  9. 位运算取第一个非0的位 r & (~(r-1))

    Single Number III Given an array of numbers nums, in which exactly two elements appear only once and ...

随机推荐

  1. CopyOnWriteArrayList 读写分离,弱一致性

    为什么会有CopyOnWriteArrayList? 我们知道ArrayList和LinkedList实现的List都是非线程安全的,于是就有了Vector,它是基于ArrayList的线程安全集合, ...

  2. 【排序基础】1、选择排序法 - Selection Sort

    文章目录 选择排序法 - Selection Sort 为什么要学习O(n^2)的排序算法? 选择排序算法思想 操作:选择排序代码实现 选择排序法 - Selection Sort 简单记录-bobo ...

  3. 【Linux】tcpdump

    tcpdump介绍 tcpdump 是一个运行在命令行下的抓包工具.它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包.tcpdump 适用于 大多数的类Unix系统操作系统 ...

  4. yml文件中${DB_HOST:localhost}的含义

    引自:https://blog.csdn.net/chen462488588/article/details/109057342 今天学习eladmin项目中看到application-dev.yml ...

  5. python-列表包字典-根据字典的某一个键的值来进行排序

    python-列表包字典-根据字典的某一个键的值来进行排序 列表包字典的数据结构 要实现按照字典中的某一个键所对应的值进行排序 有两种办法 方法一,使用列表的sort方法 由小到大排 列表.sort( ...

  6. Databricks 第9篇:Spark SQL 基础(数据类型、NULL语义)

    Spark SQL 支持多种数据类型,并兼容Python.Scala等语言的数据类型. 一,Spark SQL支持的数据类型 整数系列: BYTE, TINYINT:表示1B的有符号整数 SHORT, ...

  7. Mybatis【15】-- Mybatis一对一多表关联查询

    注:代码已托管在GitHub上,地址是:https://github.com/Damaer/Mybatis-Learning ,项目是mybatis-11-one2one,需要自取,需要配置maven ...

  8. CentOS7 通过snat进行上网

    需求: 有两台服务器,一台绑定了弹性公网IP,另外一台没有,需要内网服务器通过有弹性ip的机器代理进行上网. 环境: centos7 操作系统 服务器A: 192.168.0.18 (可以上网,有弹性 ...

  9. Databricks 第10篇:Job

    Job是立即运行或按计划运行notebook或JAR的一种方法,运行notebook的另一种方法是在Notebook UI中以交互方式运行. 一,使用UI来创建Job 点击"Jobs&quo ...

  10. TekRADIUS5.5安装教程

    1.下载地址:https://www.kaplansoft.com/TekRADIUS/release/tekradius.zip 2.解压安装,双击一步默认安装下来就是了 3.配置连接数据库: 4. ...