HDU 4370 0 or 1
2015-09-08 15:09
316 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4370```
这道题目,如果不是在图论专题里面,真的看不出来是一道图论题,说明图论的思维还不够。首先分析那个矩阵的三个表达式,由于C矩阵类似于邻接矩阵,而最后要求的求和可以等价于走一段符合一定条件的路,使得所经过的边的权值总和最小,那么这条路就可以转化为一个类似于最短路的问题了。为什么会想到这个,有三个表达式可以得到。
1)
1.X 12+X 13+...X 1n=1
这个可以表示1号点的出度为1。
2)
2.X 1n+X 2n+...X n-1n=1
这个可以表示,n号点的入度为1。
3)
3.for each i (1<i<n), satisfies ∑X ki (1<=k<=n)=∑X ij (1<=j<=n).
每一个点的出度和入度相同。这样就正好可以形成一个图了,你们看出来没有?
可惜,根据官方题解,这并不是全部的情况,少掉了环的情况。(话说图里面真的要考虑各种环-
-)从1出发走一个最小花费的环,从n出发,再走一个最小花费的环,那么两个环的花费和也可能是答案。(这谁知道,还是自己思维太差了)好吧,思路就是这样,那么有一个问题就是怎么求最小花费环,由于这个图是完全图,所以最小花费环肯定是到某一个点,然后直接回来,所以只要spfa更新的时候如果v==s,则cir=min(cir,d[u]+g[u][v])。具体看代码吧。``````
这道题目,如果不是在图论专题里面,真的看不出来是一道图论题,说明图论的思维还不够。首先分析那个矩阵的三个表达式,由于C矩阵类似于邻接矩阵,而最后要求的求和可以等价于走一段符合一定条件的路,使得所经过的边的权值总和最小,那么这条路就可以转化为一个类似于最短路的问题了。为什么会想到这个,有三个表达式可以得到。
1)
1.X 12+X 13+...X 1n=1
这个可以表示1号点的出度为1。
2)
2.X 1n+X 2n+...X n-1n=1
这个可以表示,n号点的入度为1。
3)
3.for each i (1<i<n), satisfies ∑X ki (1<=k<=n)=∑X ij (1<=j<=n).
每一个点的出度和入度相同。这样就正好可以形成一个图了,你们看出来没有?
可惜,根据官方题解,这并不是全部的情况,少掉了环的情况。(话说图里面真的要考虑各种环-
-)从1出发走一个最小花费的环,从n出发,再走一个最小花费的环,那么两个环的花费和也可能是答案。(这谁知道,还是自己思维太差了)好吧,思路就是这样,那么有一个问题就是怎么求最小花费环,由于这个图是完全图,所以最小花费环肯定是到某一个点,然后直接回来,所以只要spfa更新的时候如果v==s,则cir=min(cir,d[u]+g[u][v])。具体看代码吧。``````
// // Created by CQU_CST_WuErli // Copyright (c) 2015 CQU_CST_WuErli. All rights reserved. // // #include<bits/stdc++.h> #include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <cctype> #include <cmath> #include <string> #include <vector> #include <list> #include <map> #include <queue> #include <stack> #include <set> #include <algorithm> #include <sstream> #define CLR(x) memset(x,0,sizeof(x)) #define OFF(x) memset(x,-1,sizeof(x)) #define MEM(x,a) memset((x),(a),sizeof(x)) #define ALL(x) x.begin(),x.end() #define AT(i,v) for (auto &i:v) #define For_UVa if (kase!=1) cout << endl #define BUG cout << "I am here" << endl #define lookln(x) cout << #x << "=" << x << endl #define look(x) cout << #x << "=" << x #define SI(a) scanf("%d",&a) #define SII(a,b) scanf("%d%d",&a,&b) #define SIII(a,b,c) scanf("%d%d%d",&a,&b,&c) #define root 1,n,1 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define BigInteger bign const int MAX_L=2005;// For BigInteger const int INF_INT=0x3f3f3f3f; const long long INF_LL=0x7fffffff; const int MOD=1e9+7; const double eps=1e-9; const double pi=acos(-1); typedef long long ll; using namespace std; int g[330][330]; int n; int vis[330],d[330],dr[330]; int spfa(int s,int *dp){ CLR(vis); for (int i=1;i<=n;i++) dp[i]=INF_INT; int cir=INF_INT; queue<int> q; for (int i=1;i<=n;i++){ if (i==s) continue; q.push(i); vis[i]=1; dp[i]=g[s][i]; } while (!q.empty()){ int x=q.front();q.pop(); vis[x]=0; for (int i=1;i<=n;i++){ int v=i; if (dp[v]>dp[x]+g[x][v]){ dp[v]=dp[x]+g[x][v]; if (!vis[v]) { q.push(v); vis[v]=1; } if (v==s) { cir=min(cir,dp[x]+g[x][v]); } } } } return cir; } int main(){ #ifdef LOCAL freopen("C:\\Users\\john\\Desktop\\in.txt","r",stdin); // freopen("C:\\Users\\john\\Desktop\\out.txt","w",stdout); #endif while (cin >> n){ for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) scanf("%d",&g[i][j]); int cir_1,cir_n; cir_1=spfa(1,d); cir_n=spfa(n,dr); // cout << d << ' ' << dr[1] << endl; // cout <<cir_1 << ' ' << cir_n << endl; cout << min(d ,cir_1+cir_n) << endl; } return 0; }
相关文章推荐
- php解析http获取的json字符串变量总是空白null
- 修改map分片个数
- BZOJ 2190 仪仗队(欧拉函数)
- 【LeetCode】111. Minimum Depth of Binary Tree
- 使用递归算法结合数据库解析成java树形结构
- 微信公众帐号开发教程第5篇-各种消息的接收与响应
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- OAF学习笔记-19-在客制页面做出Tab(标签页)
- 树莓派2B安装OpenCV 2.4.11