HDU 4370 0 or 1

来源:互联网 发布:全境封锁 网络优化 编辑:程序博客网 时间:2024/06/05 00:33

题目链接: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])。具体看代码吧。``````


////  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 bignconst int MAX_L=2005;// For BigIntegerconst 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 LOCALfreopen("C:\\Users\\john\\Desktop\\in.txt","r",stdin);//freopen("C:\\Users\\john\\Desktop\\out.txt","w",stdout);#endifwhile (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[n] << ' ' << dr[1] << endl;//cout <<cir_1 << ' ' << cir_n << endl;cout << min(d[n],cir_1+cir_n) << endl;} return 0;}


0 0