0 or 1

题目链接:

Rhttp://acm.hust.edu.cn/vjudge/contest/122685#problem/R

Description


```
Given a n*n matrix C ij (1Besides,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.

</big>

##Input
<big>
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 C ij(0<=C ij<=100000).
</big> ##Output
<big>
For each case, output the minimum of ∑C ij*X ij you can get.
</big> ##Sample Input
<big>
4
1 2 4 10
2 0 1 1
2 2 0 5
6 3 1 2
</big> ##Sample Output
<big>
3
</big> ##Hint
<big>
</big> <br/>
##题意:
<big>
求满足题目条件的最小和.
</big> <br/>
##题解:
<big>
一道多校的好题,一开始还是以为是个dp什么的,看了题解才知道居然可以用图论做.
题目的条件分别表示:起点出度为1,终点入度为1,其他点出入度相等.
这就描述了从起点到终点的一条简单路径. 即求最短路.
考虑特殊情况还需要记录起点和终点的最小环(非自环).
<br/>
详细题解参考下面的第二份代码.
</big> <br/>
##代码:
``` cpp
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define LL long long
#define eps 1e-8
#define maxn 310
#define mod 1000000007
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std; int n;
int value[maxn][maxn];
int dis[maxn];
int pre[maxn];
bool vis[maxn]; int dijkstra(int s) {
int cir = inf; // 最小花费环(经过s)
memset(vis, 0, sizeof(vis));
memset(pre, -1, sizeof(pre));
for(int i=1; i<=n; i++) dis[i] = inf; dis[s] = 0; for(int i=1; i<=n; i++) {
int p, mindis = inf;
for(int j=1; j<=n; j++) {
if(!vis[j] && dis[j]<mindis)
mindis = dis[p=j];
}
vis[p] = 1;
for(int j=1; j<=n; j++) {
if(j==s && p!=s) //不能是自环
cir = min(cir, dis[p]+value[p][s]);
if(dis[j] > dis[p]+value[p][j]) {
dis[j] = dis[p] + value[p][j];
pre[j] = p;
}
}
} return cir;
} int main(void)
{
//IN; while(scanf("%d", &n) != EOF && n)
{
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++) {
int x; scanf("%d", &x);
value[i][j] = x;
} int cir1 = dijkstra(n);
int cir2 = dijkstra(1); int ans = min(dis[n], cir1+cir2); printf("%d\n", ans);
} return 0;
}

参考题解及代码:

/*
HDU 4370 0 or 1
转换思维的题啊,由一道让人不知如何下手的题,转换为了最短路
基本思路就是把矩阵看做一个图,图中有n个点,1号点出度为1,
n号点入度为1,其它点出度和入度相等,路径长度都是非负数, 等价于一条从1号节点到n号节点的路径,故Xij=1表示需要经
过边(i,j),代价为Cij。Xij=0表示不经过边(i,j)。注意到Cij非负
且题目要求总代价最小,因此最优答案的路径一定可以对应一条简单路径。 最终,我们直接读入边权的邻接矩阵,跑一次1到n的最短路即可,记最短路为path。 漏了如下的情况B:
从1出发,走一个环(至少经过1个点,即不能
是自环),回到1;从n出发,走一个环(同理),回到n。
也就是1和n点的出度和入度都为1,其它点的出度和入度为0. 由于边权非负,于是两个环对应着两个简单环。 因此我们可以从1出发,找一个最小花费环,记代价为c1,
再从n出发,找一个最小花费环,记代价为c2。
(只需在最短路算法更新权值时多加一条记录即可:if(i==S) cir=min(cir,dis[u]+g[u][i])) 故最终答案为min(path,c1+c2)
*/
/*
本程序用SPFA来完成最短路。
但是由于要计算从出发点出发的闭环的路径长度。
所以要在普通SPFA的基础上做点变化。 就是把dist[start]设为INF。同时一开始并不是让出发点入队,而是让
出发点能够到达的点入队。
*/
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std; const int INF=0x3f3f3f3f;
const int MAXN=330;
int cost[MAXN][MAXN];//保存路径长度的邻接矩阵
int dist[MAXN];
int que[MAXN];//注意队列的循环利用,建成循环队列
bool vis[MAXN];//是否在队列中标记 void SPFA(int start,int n)
{
int front=0,rear=0;
for(int v=1;v<=n;v++)//初始化
{
if(v==start)//由于要找start的闭环,所以dist[start]设为INF,且不入队
{
dist[v]=INF;
vis[v]=false;
}
else if(cost[start][v]!=INF)
{
dist[v]=cost[start][v];
que[rear++]=v;
vis[v]=true;
}
else//即dist[start][v]==INF情况,对本题没有这种情况
{
dist[v]=INF;
vis[v]=false;
}
} while(front!=rear)//注意这个条件是不等,因为是循环队列
{
int u=que[front++];
for(int v=1;v<=n;v++)
{
if(dist[v]>dist[u]+cost[u][v])
{
dist[v]=dist[u]+cost[u][v];
if(!vis[v])//不在队列
{
vis[v]=true;
que[rear++]=v;
if(rear>=MAXN) rear=0;//循环队列
}
}
}
vis[u]=false;
if(front>=MAXN)front=0;
} }
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&cost[i][j]);
SPFA(1,n);
int ans=dist[n];//1到n的最短路
int loop1=dist[1];//1的闭环长度
SPFA(n,n);
int loopn=dist[n];//n的闭环长度
ans=min(ans,loop1+loopn);
printf("%d\n",ans);
}
return 0;
}

HDU 4370 0 or 1 (最短路+最小环)的更多相关文章

  1. HDU - 4370 0 or 1 最短路

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

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

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

  3. HDU - 4370 0 or 1

    0 or 1 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  4. hdu 4370 0 or 1,最短路

    题目描述 给定n * n矩阵C ij(1 <= i,j <= n),我们要找到0或1的n * n矩阵X ij(1 <= i,j <= n). 此外,X ij满足以下条件: 1. ...

  5. HDU 4370 0 or 1(转化为最短路)题解

    思路:虽然是最短路专题里的,但也很难想到是最短路,如果能通过这些关系想到图论可能会有些思路.我们把X数组看做邻接矩阵,那么三个条件就转化为了:1.1的出度为1:2.n的入度为1:3.2~n-1的出度等 ...

  6. HDU 4370 0 or 1(spfa+思维建图+计算最小环)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4370 题目大意:有一个n*n的矩阵Cij(1<=i,j<=n),要找到矩阵Xij(i< ...

  7. 思维题(转换) HDU 4370 0 or 1

    题目传送门 题意:题目巨晦涩的传递出1点和n点的初度等于入度等于1, 其余点出度和入度相等 分析:求最小和可以转换成求最短路,这样符合条件,但是还有一种情况.1点形成一个环,n点也形成一个环,这样也是 ...

  8. (中等) HDU 4370 0 or 1,建模+Dijkstra。

    Description Given a n*n matrix C ij (1<=i,j<=n),We want to find a n*n matrix X ij (1<=i,j&l ...

  9. HDU 4370 0 or 1 (01规划)【Dijkstra】||【spfa】

    <题目链接> 题目大意: 一个n*n的01矩阵,满足以下条件 1.X12+X13+...X1n=12.X1n+X2n+...Xn-1n=13.for each i (1<i<n ...

随机推荐

  1. Android开发之源码:多次点击事件的原理和实现

    多次点击事件 多次点击事件原理:最后一次点击事件与第一次点击事件的时间间隔是否小于某个时间,当小于的时候,就认为这是一个多次点击事件. Android源码实现效果: import android.ap ...

  2. CY7C68013A的一点总结

    一. 值得参考的资料:FX2 TechRefManual.USB应用开发宝典. LabVIEW-USB通信简单教程(用于参考生成labview驱动程序).USB设备请求和描述符整理(仅用于理解描述符的 ...

  3. NodeJS常用库说明

    underscore:1.合并json async:1.异步编程同步化

  4. Toad创建DBLINKsop

    Toad创建DBLINKsop 1.创建服务: 点击“测试”,出现如下测试窗口后点击更改登录,用户名和密码数据目标主机用户名.密码; 出现如下窗口后,点击“关闭”,然后点击“完成”即可; 2.创建db ...

  5. Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 53

    项目问题解析“Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 53.”这个问题是最近调试app的时 ...

  6. LeetCode: Binary Tree Level Order Traversal && Binary Tree Zigzag Level Order Traversal

    Title: Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to ...

  7. zoj 1842 Prime Distance

    // 数论题,增强的筛法,回想素数筛法 // 只要筛到最大数的开方,剩下的就是素数 // 于是这里,开一个 sqrt(2^31) 大约 65536 的素数表,然后 // 对于每个 L~U 的区间,筛掉 ...

  8. Creating SharePoint 2010 Event Receivers in Visual Studio 2010

    转:http://msdn.microsoft.com/en-us/library/gg252010(v=office.14).aspx Summary:  Learn how to create a ...

  9. How to Download APK Files from Google Play Store

    Evozi, an Android app developer, offers a one-click online APK download app that lets you download t ...

  10. HDU 5489 Removed Interval

    题意:求一段序列中删掉L个连续元素后的LIS. 解法:我的想法很复杂= =怎么说呢……首先用nlogn的方法求LIS得到的序列dp的第i项的意义为上升子序列所有长度为i的序列结尾元素的最小值,那么先倒 ...