[kuangbin带你飞]专题四 最短路练习 R
2016-12-29 15:18
411 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4370
HDU 4370 0 or 1(最短路)
这是整套里面我觉得最有意思的一道最短路,也确实让我觉得我与真正acmer之间的距离还是很大的
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 (1in), 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.
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).
究竟怎么就是最短路了呢?
首先啊,如果每行的数字都缩成一个点,且如果X(i,j) = 1 那么我们连边i->j,如果是0的话,乘cij之后和没有是一样的,所以不管他,那么 连边i->j什么意思呢?
第三个条件是,第i行的x和等于第i列x和对吧,那么从i出去多少条边就是第i行多少个1 ,也就是第i行的和,换句话说:i点的出度就是∑Xij 。
那么当X(i,j)=1时,第j列是不是出现了一个1?也就是说第j列的和:+1了。连边所以的i->j后,就是所有第几行第j列是1了,点j的入度自然就是第j列的和。
那么第三个条件就是: 2~n-1这些节点,满足:入度 = 出度!
第二个条件是 :n号节点的入度为1
第一个条件: 1号节点的出度为1
然后基于这个思想,每个边权值为c(i,j)
1->n的最短路就是答案,x为0的就是不选的边,下= 1的就是选的边,边的选择就交给最短路了,
这个时候,我又错了。。。
只考虑1->n是不行的,因为可能1->..->1中间没有n和n ->…->n这两个路放在一起是最小的,那么单纯的最短路就不对了咯。我们需要搞两种,在比较一下就好了,这个的处理就是之前的dist【1】先为无穷,所以1直接可达的点放队列,dijstra一下,就可以球出来1->1 1->n的最短路了,那么n->n呢?
我是选择了在一个dij,然后就ac了==
HDU 4370 0 or 1(最短路)
这是整套里面我觉得最有意思的一道最短路,也确实让我觉得我与真正acmer之间的距离还是很大的
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 (1in), 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.
题意:
给你一个n*n的矩阵,然后让咱们构造另一个n*n的矩阵,构造的矩阵有如下要求,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).
tip:
额。。这个题解写着好虚啊,毕竟不是自己想的。究竟怎么就是最短路了呢?
首先啊,如果每行的数字都缩成一个点,且如果X(i,j) = 1 那么我们连边i->j,如果是0的话,乘cij之后和没有是一样的,所以不管他,那么 连边i->j什么意思呢?
第三个条件是,第i行的x和等于第i列x和对吧,那么从i出去多少条边就是第i行多少个1 ,也就是第i行的和,换句话说:i点的出度就是∑Xij 。
那么当X(i,j)=1时,第j列是不是出现了一个1?也就是说第j列的和:+1了。连边所以的i->j后,就是所有第几行第j列是1了,点j的入度自然就是第j列的和。
那么第三个条件就是: 2~n-1这些节点,满足:入度 = 出度!
第二个条件是 :n号节点的入度为1
第一个条件: 1号节点的出度为1
然后基于这个思想,每个边权值为c(i,j)
1->n的最短路就是答案,x为0的就是不选的边,下= 1的就是选的边,边的选择就交给最短路了,
这个时候,我又错了。。。
只考虑1->n是不行的,因为可能1->..->1中间没有n和n ->…->n这两个路放在一起是最小的,那么单纯的最短路就不对了咯。我们需要搞两种,在比较一下就好了,这个的处理就是之前的dist【1】先为无穷,所以1直接可达的点放队列,dijstra一下,就可以球出来1->1 1->n的最短路了,那么n->n呢?
我是选择了在一个dij,然后就ac了==
#include <cstdio> #include <iostream> #include <cstring> #include <queue> #include <vector> using namespace std; const int maxn = 300*300+10; const int maxm = 1e6+10; int n,tot,head[maxn],dist[maxn],dis[maxn]; typedef pair<int,int>pii; priority_queue<pii,vector<pii>,greater<pii> >q,p; struct node{ int v,w,next; }edges[maxm]; void add(int u,int v,int w){ edges[tot].v = v;edges[tot].w= w;edges[tot].next = head[u];head[u]=tot++; } void init(){ memset(head,-1,sizeof(head)); tot =0; dist[1] = (1<<30); dis = (1<<30); for(int i = 1 ; i <= n ; i++){ for(int j = 1 ; j <= n ; j++){ int w; scanf("%d",&w); add(i,j,w); if(i == 1&&j!=1){ q.push(make_pair(w,j)); dist[j] = w; } if(i == n&&j!=n){ p.push(make_pair(w,j)); dis[j] = w; } } } } void dij(){ while(!q.empty()){ pii tmp = q.top(); q.pop(); for(int k = head[tmp.second];k!=-1;k=edges[k].next){ if(dist[edges[k].v] > dist[tmp.second]+edges[k].w){ dist[edges[k].v] = dist[tmp.second]+edges[k].w; q.push(make_pair(dist[edges[k].v],edges[k].v)); } } } } void di(){ while(!p.empty()){ pii tmp = p.top(); p.pop(); for(int k = head[tmp.second];k!=-1;k=edges[k].next){ if(dis[edges[k].v] > dis[tmp.second]+edges[k].w){ dis[edges[k].v] = dis[tmp.second]+edges[k].w; p.push(make_pair(dis[edges[k].v],edges[k].v)); } } } } void sov(){ dij(); di(); printf("%d\n",min(dist ,dist[1]+dis )); } int main(){ while(~scanf("%d",&n)){ init(); sov(); } }
相关文章推荐
- 【算法系列学习】SPFA邻接表最短路 [kuangbin带你飞]专题四 最短路练习 F - Wormholes
- [kuangbin带你飞]专题四 最短路练习 E POJ 1860
- [kuangbin带你飞]专题四 最短路练习H,I,J
- [kuangbin带你飞]专题四 最短路练习 K POJ 3159
- [kuangbin带你飞]专题四 最短路练习 A
- [kuangbin带你飞]专题四 最短路练习-G
- [kuangbin带你飞]专题四 最短路练习 K(差分约束)L
- [kuangbin带你飞]专题四 最短路练习 A-E
- [kuangbin带你飞]专题四 最短路练习
- [kuangbin带你飞]专题四 最短路练习 B
- [kuangbin带你飞]专题四 最短路练习 S POJ 3169
- [kuangbin带你飞]专题四 最短路练习 O LightOJ 1074
- [kuangbin带你飞]专题四 最短路练习 C
- [kuangbin带你飞]专题四 最短路练习 A POJ 2387
- [kuangbin带你飞]专题四 最短路练习 G POJ 1502
- [kuangbin带你飞]专题四 最短路练习 I POJ 2240
- [kuangbin带你飞]专题四 最短路练习 B POJ 2253
- [kuangbin带你飞]专题四 最短路练习 L POJ 2502
- [kuangbin带你飞]专题四 最短路练习 C POJ 1797
- [kuangbin带你飞]专题四 最短路练习 H POJ 3660