HDU - 4370 0 or 1 最短路

Posted ckxkexing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 4370 0 or 1 最短路相关的知识,希望对你有一定的参考价值。

HDU - 4370

参考:https://www.cnblogs.com/hollowstory/p/5670128.html

题意:

  给定一个矩阵C, 构造一个A矩阵,满足条件:

    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).

  使得∑Cij*Xij(1<=i,j<=n)最小。

思路:

  理解条件之前先转换一下思维,将矩阵C看做描述N个点花费的邻接矩阵
  再来看三个条件:
    条件一:表示1号点出度为1
    条件二:表示n号点入度为1
    条件三:表示k( 1 < k < n )号点出度等于入度
  最后再来看看题目要求,∑Cij*Xij(1<=i,j<=n),很明显,这是某个路径的花费,而路径的含义可以有以下两种:
  一:1号点到n号点的花费
  二:1号点经过其它点成环,n号点经过其它点成环,这两个环的花费之和
  于是,就变成了一道简单的最短路问题
  关于环花费的算法,可以改进spfa算法,初始化dis[start] = INF,且一开始让源点之外的点入队
技术分享图片
#include <algorithm>
#include  <iterator>
#include  <iostream>
#include   <cstring>
#include   <cstdlib>
#include   <iomanip>
#include    <bitset>
#include    <cctype>
#include    <cstdio>
#include    <string>
#include    <vector>
#include     <stack>
#include     <cmath>
#include     <queue>
#include      <list>
#include       <map>
#include       <set>
#include   <cassert>

using namespace std;
//#pragma GCC optimize(3)
//#pragma comment(linker, "/STACK:102400000,102400000")  //c++
// #pragma GCC diagnostic error "-std=c++11"
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3)

#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "
";
#define pb push_back
#define pq priority_queue



typedef long long ll;
typedef unsigned long long ull;

typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3;

//priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl ‘
‘

#define OKC ios::sync_with_stdio(false);cin.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A)  //用来压行
#define REP(i , j , k)  for(int i = j ; i <  k ; ++i)
#define max3(a,b,c) max(max(a,b), c); 
//priority_queue<int ,vector<int>, greater<int> >que;

const ll mos = 0x7FFFFFFF;  //2147483647
const ll nmos = 0x80000000;  //-2147483648
const int inf = 0x3f3f3f3f;       
const ll inff = 0x3f3f3f3f3f3f3f3f; //18
// const int mod = 10007;
const double esp = 1e-8;
const double PI=acos(-1.0);
const double PHI=0.61803399;    //黄金分割点
const double tPHI=0.38196601;


template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<0||ch>9) f|=(ch==-),ch=getchar();
    while (ch>=0&&ch<=9) x=x*10+ch-0,ch=getchar();
    return x=f?-x:x;
}


/*-----------------------showtime----------------------*/
            const int maxn = 309;
            int n;
            int dis[maxn],a[maxn][maxn],vis[maxn];
            void spfa(int s){
                stack<int>q;
                for(int i=1; i<=n; i++){
                    dis[i] = a[s][i];
                    if(i!=s){
                        q.push(i);
                        vis[i] = true;
                    } 
                    else vis[i] = false;
                }
                dis[s] = inf;
                while(!q.empty()){
                    int u = q.top();q.pop();
                    vis[u] = false;
                    for(int i=1; i<=n; i++){
                        if(u==i)continue;
                        if(dis[i] > dis[u] + a[u][i]){
                            dis[i] = dis[u] + a[u][i];
                            if(vis[i] == false)q.push(i), vis[i] = true;
                        }
                    }
                }
            }

int main(){
            while(~scanf("%d", &n)){
                for(int i=1; i<=n; i++){
                    for(int j=1; j<=n; j++){
                        scanf("%d", &a[i][j]);  
                    }
                }
                spfa(1);
                int ans = dis[n];
                int a1 = dis[1];
                spfa(n);
                a1 += dis[n];
                printf("%d
", min(a1, ans));
            }
            return 0;   
}
HDU4370

 

以上是关于HDU - 4370 0 or 1 最短路的主要内容,如果未能解决你的问题,请参考以下文章

HDU-4370 '0 or 1' 最短路 要考虑连通性

Q - 0 or 1 HDU - 4370 (spfa最短路+最小环)

hdu4370 dijkstra矩阵转单向边最短路矩阵+自环闭环

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

HDU 4370 0 or 1 最小环

HDU 3342 Legal or Not (最短路 拓扑排序?)