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. Flutter 布局类组件:流式布局(Wrap和Flow)

    前言 把超出屏幕显示范围会自动折行的布局称为流式布局.Flutter中通过Wrap和Flow来支持流式布局,将Row换成Wrap后溢出部分则会自动折行. Wrap 接口描述 Wrap({ Key ke ...

  2. JAR冲突问题的解决以及运行状态下如何查看加载的类

    今天碰到群里小伙伴问,线上程序好像有多个不同版本的Netty包,怎么去看到底加载了哪一个? 在说如何看之前,先来说说,当你开始意识到项目里有多个不同版本的Jar包,都是因为遇到了这几个异常: java ...

  3. 【Linux】扩大swap分区

    今天安装oracle的时候,提示我swap分区过小.需要最少3g以上 但是安装系统了,想要扩大swap分区怎么办呢 下面来介绍如何扩大swap分区 按步骤介绍 Red Hat linux 如何增加sw ...

  4. 深入解析vue响应式原理

    摘要:本文主要通过结合vue官方文档及源码,对vue响应式原理进行深入分析. 1.定义 作为vue最独特的特性,响应式可以说是vue的灵魂了,表面上看就是数据发生变化后,对应的界面会重新渲染,那么响应 ...

  5. M8 E147 不可能为条目*确立账户

    今天用BAPI做发票校验, BAPI_INCOMINGINVOICE_CREATE这个函数使用都正常,可是突然就无法做发票检验了 报了个错误,"不可能为条目BOXT TR 确立账户" ...

  6. CodeMonkey少儿编程第2章 turnTo对象

    目标 了解对象的概念 了解方法与对象的关系 掌握turnTo指令的用法 在开始本章的学习之前,我们先来复习一下上一章的知识点. 在第1章中,我们学会了在这个游戏中最简单的两个指令. step x 其中 ...

  7. QT串口助手(三):数据接收

    作者:zzssdd2 E-mail:zzssdd2@foxmail.com 一.前言 开发环境:Qt5.12.10 + MinGW 实现的功能 串口数据的接收 ascii字符形式显示与hex字符形式显 ...

  8. MYSQL基础知识的复习2

    1.修改表中的数据 update 表名 set 要修改的字段 where 条件;-- 如果修改多个字段那么字段和字段之间用逗号隔开 2.查询(很重要) 1.查询表中部分字段: select 字段名,字 ...

  9. 2020年12月18号--21号 人工智能(深度学习DeepLearning)python、TensorFlow技术实战

    深度学习DeepLearning(Python)实战培训班 时间地点: 2020 年 12 月 18 日-2020 年 12 月 21日 (第一天报到 授课三天:提前环境部署 电脑测试) 一.培训方式 ...

  10. 简单监控liunx中cpu、内存、磁盘及发送邮件参考

    shell脚本 vim jk.sh  #命名脚本名   #!/bin/bash time=`date "+%Y-%m-%d %H:%M:%S"`      #定义时间 echo & ...