1. 程式人生 > >新年好(單源最短路(Dijkstra)+子集生成)

新年好(單源最短路(Dijkstra)+子集生成)

【問題描述】
 
  重慶城裡有n個車站,m條雙向公路連線其中的某些站。每兩個車站最多用一條公路直接相連,從任何一個車站出發都可以經過一條或多條公路到達其它車站,但不同的路徑需要花費的時間可能不同。在一條路徑上花費的時間等於路徑上所有公路需要的時間和。


  佳佳的家在車站1,他有五個親戚,分別住在車站a、b、c、d、e。過年了,他需要從自己的家出發,拜訪每個親戚(順序任意),給他們送去節日的祝福。怎樣走,才需要最少的時間? 
 
【輸入格式】
 
  第一行:n(n<=50,000),m(m<=100,000),為車站數目和公路的數目。 
  第二行:a、b、c、d、e,為五個親戚所在車站編號(1< a、b、c、d、e <= n)。 
  接下來m行,每行三個整數x、y、t( 1 <= x、y <= n,1 <= t <= 100),為公路連線的兩個車站編號和時間。 


 
【輸出格式】
 
  僅一行,包含一個整數T,為最少的總時間
 
【輸入樣例】
 
6 6
2 3 4 5 6
1 2 8
2 3 3
3 4 4
4 5 5
5 6 2
1 6 7


 
【輸出樣例】
 
21
 
【資料範圍】
 
n<=50,000

m<=100,000

分析:

一,最短路問題,自然想到三大演算法;

二,五個點加上起點總共6個點,第一個點是1,固定的,其它點順序任意,不好一遍處理完;但是總共才6個點,所以可以想到每個點來一次單源最短路,分別用一個dist陣列記錄;然後就是列舉所有可能的排列,求最小的路徑即可

#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=50005;
const int maxm=100005;
const int INF=150000000;
int n,m,np=0,last[maxn],rela[6],dist[6][maxn];
struct edge{int to,w,pre;}E[maxm*2];
struct data
{
	int d,id;
	friend bool operator < (data a,data b) {return a.d>b.d;}
};

char c;
inline void qkscanf(int &x)
{
	for(c=getchar();c<'0'||c>'9';c=getchar());
	for(x=0;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
}

inline void addedge(int u,int v,int w)
{
	E[++np]=(edge){v,w,last[u]};
	last[u]=np;
}

int done[maxn];
inline void Dijkstra(int s,int *dis)
{
	priority_queue<data>pq;
	for(int i=1;i<=n;i++) dis[i]=INF,done[i]=0;
	pq.push((data){0,s});
	dis[s]=0;
	while(!pq.empty())
	{
		data t=pq.top();pq.pop();
		int i=t.id;
		if(done[i]) continue;
		done[i]=1;
		for(int p=last[i];p;p=E[p].pre)
		{
			int j=E[p].to,w=E[p].w;
			if(dis[j]>dis[i]+w)
			{
				dis[j]=dis[i]+w;
				pq.push((data){dis[j],j});
			}
		}
	}
}

int order[6];
int ans=INF;
inline void check()
{
	int cnt=0;
	for(int i=0;i<5;i++)
	{
		int x=order[i],y=rela[order[i+1]];//i點到i+1號點的距離 
		cnt+=dist[x][y];
	}
	ans=min(ans,cnt);
}

int vis[6];
inline void DFS(int cnt)
{
	if(cnt>5)//生成了一個排列 
	{
		check();
		return;
	}
	
	for(int i=1;i<=5;i++)
	{
		if(!vis[i])
		{
			vis[i]=1;
			order[cnt]=i;//記錄點在rela陣列中的下標,而不是點本身 
			DFS(cnt+1);
			vis[i]=0;
		}
	}
}

int main()
{
//	freopen("in.txt","r",stdin);
	//input
	qkscanf(n);qkscanf(m);
	for(int i=1;i<=5;i++) qkscanf(rela[i]);
	register int u,v,w;
	for(int i=1;i<=m;i++)
	{
		qkscanf(u);qkscanf(v);qkscanf(w);
		addedge(u,v,w);addedge(v,u,w);
	}
	//solve
	rela[0]=1;//起點是1 
	for(int i=0;i<=5;i++) Dijkstra(rela[i],dist[i]);//每個點求最短路 
	order[0]=0;//順序中,第一個點必須是1(rela陣列中下標為0) 
	DFS(1);
	printf("%d",ans);
}

相關推薦

新年短路Dijkstra+子集生成

【問題描述】   重慶城裡有n個車站,m條雙向公路連線其中的某些站。每兩個車站最多用一條公路直接相連,從任何一個車站出發都可以經過一條或多條公路到達其它車站,但不同的路徑需要花費的時間可能不同。在一條路徑上花費的時間等於路徑上所有公路需要的時間和。  佳佳的家在車站1,他有五

L - New Game短路dijkstra

Description Eagle Jump公司正在開發一款新的遊戲。Hifumi Takimoto作為其中的員工,獲得了提前試玩的機會。現在她正在試圖通過一個迷宮。 這個迷宮有一些特點。為了方便描述,我們對這個迷宮建立平面直角座標系。迷宮中有兩條平行直線 L1:Ax+By+C1=0,

迷宮遊戲短路

style 個人 遊戲 stream cstring ace tin space for 個人心得:對於復雜抽象的算法還是比較模糊,希望以後有待加強。這題就是用dijskrual算法,在算出最短時間的時候進行適當的更改,還是比較模糊。 1459 迷宮遊戲 基準時間限制:1

POJ-1511 Invitation Cards 短路+逆向

每一個 一個 nvi names ring 我們 最短路算法 span class <題目鏈接> 題目大意: 有向圖,求從起點1到每個點的最短路然後再回到起點1的最短路之和。 解題分析: 在求每個點到1點的最短路徑時,如果僅僅只是遍歷每個點,對它們每一個都進行一

短路——Bellman-Ford演算法超詳細

今天看了一下午的白書的Bellman-Ford演算法,由於能力有限,可能理解不到位。。。。 感覺就是遍歷所有邊更新點,如果有更新的點,繼續遍歷所有邊,直到沒有點更新就退出. #include <iostream> #include <stdio.h> #inc

【CodeForces - 144D】Missile Silos短路,列舉中間邊,列舉情況可能性

題幹: A country called Berland consists of n cities, numbered with integer numbers from 1to n. Some of them are connected by bid

Til the Cows Come Home短路Dijstra模板題

Til the Cows Come Home Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wakes he

Subway短路

Subway Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9121 Accepted: 2959 Description You have just moved

Floyd演算法求短路圖,資料結構

Floyd演算法思路:計算某點到其餘各點的距離,可先求該點到其中一個點的距離,其他各點類似。假設求i點到j點的距離,跳點為空時,最短距離就是i到j的最短距離,跳點為1時,最短距離為D[i][j] = min{D[i][j],D[i][1]+D[1][j]},跳點為1和2時,最短距離為D[i][j]=min{D

hdu 2544 短路問題 dijkstra+堆優化模板

尋找 問題 col .cn 入隊 ron ava iss cto 最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su

Dijstra短路【模板】裸的,鄰接矩陣

Dijstra單源最短路【模板】(裸的,鄰接矩陣) 例題:洛谷-熱浪 附:最詳細的講解 程式碼: #include <iostream> #include <cstdio> using namespace std; const int inf =

PAT (Advanced Level) Practice 1030 Travel Plan 30 分短路變式

A traveler's map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a progra

Buy a Ticket短路短路Dijkstra

Buy a Ticket Musicians of a popular band “Flayer” have announced that they are going to “make their exit” with a world tour. Of course, they wil

PAT (Advanced Level) Practice 1003 Emergency 25 分 短路變式

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some ro

PAT (Advanced Level) Practice 1030 Travel Plan 30 分短路變式

A traveler's map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to wr

短路spfa模板stl更新版

#include <iostream> #include <cstdio> #include <cmath> #include <queue> #inc

【算法】Dijkstra算法短路徑問題 鄰接矩陣和鄰接表實現

當前 prior 排序 發的 單源最短路徑 fine emp eat col Dijkstra算法可使用的前提:不存在負圈。 負圈:負圈又稱負環,就是說一個全部由負權的邊組成的環,這樣的話不存在最短路,因為每在環中轉一圈路徑總長就會邊小。 算法描述:   1.找到最

洛谷P3371短路徑Dijkstra鏈式前向星處理

jks 沒有 style bool while add 是什麽 最短 短路徑 首先講解一下鏈式前向星是什麽。簡單的來說就是用一個數組(用結構體來表示多個量)來存一張圖,每一條邊的出結點的編號都指向這條邊同一出結點的另一個編號(怎麽這麽的繞) 如下面的程序就是存鏈式前向星。(

Newcoder Metropolis短路 + Dijkstra堆優化題解

題目連結:https://www.nowcoder.com/acm/contest/203/I?tdsourcetag=s_pcqq_aiomsg來源:牛客網 思路:我們用用fa[i]表示距離i最近的大都市,dis[i]表示i距離該大都市的距離。我們先把所有大都市加入初始點,然後跑Dijkstra,如果某一

短路floyd演算法

Floyd適用無向圖和有向圖,不適用於帶負權的圖   #include<stdio.h> #include<algorithm> #include<iostream> using namespace std; int n , m; int