1. 程式人生 > >最短路習題集(hdu)

最短路習題集(hdu)

下面把在杭電刷題的最短路的程式碼貼上

hdu 2544

dijkstra演算法
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#define N 200
#define Y 33333110
using namespace std;
int mapp[N][N],mark[N],dist[N],n,m;
void dijstra(){
    int i,j,minn,k;
    for(i=1;i<=n;i++)
        dist[i]=mapp[1][i];
    mark[1]=1;
    dist[1]=0;
    for(i=1;i<n;i++){
        minn=Y;k=-1;
        for(j=1;j<=n;j++)
            if(mark[j]==0&&minn>dist[j]){
                minn=dist[j];
                k=j;
            }
        mark[k]=1;
        if(k!=-1){
            for(j=1;j<=n;j++)
                if(mark[j]==0&&mapp[k][j]<Y&&mapp[k][j]+dist[k]<dist[j])
                dist[j]=mapp[k][j]+dist[k];
        }
    }

}
int main()
{
    int i,j,a,b,c;
    while(cin>>n>>m&&n&&m){
        memset(mark,0,sizeof(mark));
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
            mapp[i][j]=Y;
        for(i=1;i<=m;i++){
            cin>>a>>b>>c;
            //if(mapp[a][b]>c)
            mapp[a][b]=mapp[b][a]=c;
        }
        dijstra();
        cout<<dist[n]<<endl;
    }
    return 0;
}
floyd演算法
/****
杭電最短路2544    http://acm.hdu.edu.cn/showproblem.php?pid=2544 
****/
#include <iostream>
#include <string.h>
#define N 1100
#define Y 0x3f3f3f3f
using namespace std;
int mapp[N][N];
int main()
{
    int n,m,a,b,c,i,j,k;
    while(cin>>n>>m&&n&&m){
    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++)
            mapp[i][j]=Y;
        mapp[i][i]=0;
    }
    for(i=0;i<m;i++){
        cin>>a>>b>>c;
        mapp[a][b]=mapp[b][a]=c;
    }
    for(k=1;k<=n;k++)
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)    ///鬆弛 
                if(mapp[i][j]>(mapp[i][k]+mapp[k][j]))
                    mapp[i][j]=mapp[i][k]+mapp[k][j];
    cout<<mapp[1][n]<<endl;
    }
    return 0;
}
SPFA演算法
#include <iostream>
#include <string.h>
#include <queue>
#define N 600
#define maxEdgeNum 10010//最多邊條數
#define inf 0x3f3f3f3f
using namespace std;
int n,m,dis[N],mapp[N][N],vis[N];
void SPFA(int start)
{
  queue<int>q;
  int i,u;
  memset(vis,0,sizeof(vis));    memset(dis,inf,sizeof(dis));
  dis[start]=0;
  q.push(start);    vis[start]=1;
  //第二步:在佇列中取點,把其vis狀態設為0,對該點相鄰的點(連線二者的邊)進行鬆弛操作,修改相鄰點的dis[]
  //並判斷相鄰的點vis[]狀態是否為0(不存在於佇列中),如果是,將其加入到佇列中
  while(!q.empty())
  {
    u=q.front(); q.pop();    vis[u]=0;
    ///鬆弛
    for(i=1;i<=n;i++)
      if(dis[u]+mapp[u][i]<dis[i])
      {
        dis[i]=dis[u]+mapp[u][i];
        if(!vis[i])//要寫在鬆弛成功的裡面
        {
          q.push(i);
          vis[i]=1;
        }
      }
  }
}
int main()
{
  int s,t;
  while(cin>>n>>m&&n&&m)
  {
    int from,to,w,i;
    memset(mapp,inf,sizeof(mapp));//初始化
    for(i=1;i<=m;i++)//無向圖,一條無向邊看為兩條有向邊
    {
      cin>>from>>to>>w;
      if(mapp[from][to]>w)
        mapp[from][to]=mapp[to][from]=w;
    }
    //cin>>s>>t;
    SPFA(1);
    if(dis[n]>=inf)
        cout<<"-1"<<endl;
    else
        cout<<dis[n]<<endl;
  }
  return 0;
}
hdu 2112 這個題目有點特殊,因為節點的編號不是數字而是字母,起始終止節點的編號也是字串,用了map,不會的請戳點選開啟連結
dijkstar演算法
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
using namespace std;
#define N 0x1f1f1f1f
int mapp[151][151],d[155],mark[151],ans;
char s1[31],s2[31];
void Dij(){
    int i,j,k,minn;
    memset(mark,0,sizeof(mark));
    for(i=1;i<ans;i++)
        d[i]=mapp[1][i];
        d[1]=0; mark[1]=1;
        for(i=1;i<=ans;i++){
            minn=N; k=-1;
            for(j=1;j<=ans;j++)
                if(minn>d[j]&&!mark[j]){
                    minn=d[j];
                    k=j;
                }
            mark[k]=1;
            if(k!=-1)
            for(j=1;j<=ans;j++){
                if(!mark[j]&&mapp[k][j]<N)
                d[j]=min(d[j],d[k]+mapp[k][j]);
            }
        }
}
int main()
{
    int i,j,c,n,k;
    map<string,int> M;
    while(scanf("%d",&n)&&n!=-1){
        k=0,ans=3;
        M.clear();//初始化。
        scanf("%s%s",s1,s2);
        if(!strcmp(s1,s2))  k=1;//若起始終止節點相等,則k為1,即一種狀態
        M[s1]=1,M[s2]=2;
        for(i=1;i<=150;i++)
            for(j=1;j<=150;j++)
                mapp[i][j]=mapp[j][i]=N;
        while(n--)  {
            scanf("%s%s%d",s1,s2,&c);
            if(!M[s1]) M[s1]=ans++;
            if(!M[s2]) M[s2]=ans++;
            mapp[M[s1]][M[s2]]=mapp[M[s2]][M[s1]]=min(mapp[M[s1]][M[s2]],c);
        }
        if(k==1)  printf("0\n");
        else {
            Dij();
            if(d[2]<N)
                printf("%d\n",d[2]);
            else
                printf("-1\n");
            }
    }
    return 0;
}
hdu 1874
#include <iostream>
#include <queue>
#include <string.h>
#define Y 111100
#define N 1100
using namespace std;
int mapp[N][N],mark[N],dist[N],n,m,s,t;
void dijsta(int v0){
    int i,j;
    for(i=0;i<n;i++)
        dist[i]=mapp[v0][i];
    mark[v0]=1;  dist[v0]=0;
    for(i=1;i<n;i++){
        int minn=Y,k=-1;
        for(j=0;j<n;j++)
            if(minn>dist[j]&&mark[j]==0)
            {   minn=dist[j];
                k=j;
            }
        mark[k]=1;
        if(k!=-1){
            for(j=0;j<n;j++)
                if(mapp[k][j]<Y&&mark[j]==0){
                    if(dist[k]+mapp[k][j]<dist[j])//更新
                        dist[j]=dist[k]+mapp[k][j];
                }
        }
    }
}
int main()
{
    int a,b,c,i,j,y=0;
    while(cin>>n>>m){
        memset(mark,0,sizeof(mark));
        memset(dist,0,sizeof(dist));
       //將鄰接矩陣初始化為無窮大
      for(i=0;i<n;i++){
            for(j=0;j<n;j++){
                mapp[i][j]=Y;
            }
        }
        for(i=0;i<m;i++){
            cin>>a>>b>>c;
            if(mapp[a][b]>c)
            mapp[a][b]=mapp[b][a]=c;
        }
        cin>>s>>t;//輸入起始點與終止點的編號
        dijsta(s);//從起始點開始尋找最短路
        y=dist[t];//dist[i]表示從起始點到i的最短距離
        if(y==Y)
            cout<<"-1"<<endl;
        else
            cout<<y<<endl;
    }

    return 0;
}
poj 1789 每行固定7的字元,每兩行不同字元的個數為兩行標號之間的距離
#include <iostream>
#include <Stdio.h>
#include <string.h>
#define N 10009
#define Y 0x3f3f3f3f
using namespace std;
int dist[N],n,mapp[N][N],mark[N];
int dijkstar(){
	int i,j,minn,k,sum=0;
	for(i=0;i<n;i++)
	dist[i]=mapp[0][i];
	dist[0]=0,mark[0]=1;
	for(i=1;i<n;i++){
		minn=Y,k=-1;
		for(j=0;j<n;j++)
			if(dist[j]<minn&&mark[j]==0){
				minn=dist[j];
				k=j;
			}
		mark[k]=1;
		if(k!=-1){
			sum+=dist[k];
			for(j=0;j<n;j++)
			if(mark[j]==0&&mapp[k][j]<dist[j])
			dist[j]=mapp[k][j];
		}
	}
	return sum;
}
int main()
{
    int m,i,j,k,l,y;
    char s[2010][10];
    while(scanf("%d",&n)&&n){
    	memset(mark,0,sizeof(mark));
    	getchar();
		for(i=0;i<n;i++)
			gets(s[i]);
		 for (i=0;i<n-1;i++){
            for(j=i+1;j<n;j++){
            	l=0;
                 for (k=0;k<7;k++)
                     if(s[i][k]!=s[j][k])
                         l++;
				mapp[j][i]=mapp[i][j]=l;
            }
         }
		 for(i=0;i<n;i++)
		 	for(j=0;j<n;j++)
		 	if(mapp[i][j]==0)
		 	mapp[i][j]=Y;
		y=dijkstar();
		printf("The highest possible quality is 1/%d.\n",y);	
	}
    return 0;
}
hdu 1596
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <iomanip>
#define N 11100
using namespace std;
double mapp[N][N],dist[N];
int mark[N],n;
void dij(int v0){
    int i,j,k;
    double minn;
    for(i=1;i<=n;i++)
        dist[i]=mapp[v0][i];
    dist[v0]=0; mark[v0]=1;
    for(i=1;i<n;i++){
        minn=0; k=-1;
        for(j=1;j<=n;j++)
            if(dist[j]>minn&&mark[j]==0){
                minn=dist[j];
                k=j;
            }
        mark[k]=1;
        if(k!=-1)
            for(j=1;j<=n;j++)
                if(!mark[j]&&dist[k]*mapp[k][j]>dist[j])
                   dist[j]=dist[k]*mapp[k][j];
    }
}
int main()
{
    int i,j,m,a,b;
    while(scanf("%d",&n)!=EOF){
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
        scanf("%lf",&mapp[i][j]);
    scanf("%d",&m);
    for(i=0;i<m;i++){
        memset(mark,0,sizeof(mark));
        scanf("%d %d",&a,&b);
        dij(a);
        if(dist[b]==0)
            printf("What a pity!\n");
        else
            printf("%.3lf\n",dist[b]);
        }
    }
    return 0;
}


相關推薦

短路習題集hdu

下面把在杭電刷題的最短路的程式碼貼上 hdu 2544 dijkstra演算法 #include <iostream> #include <algorithm> #include <stdio.h> #include <strin

短路模板——用拓撲排序解決有向無環圖中的短路

測試資料: 8 13 5 4 0.35 4 7 0.37 5 7 0.28 5 1 0.32 4 0 0.38 0 2 0.26 3 7 0.39 1 3 0.29 7 2 0.34 6 2 0.40 3 6 0.52 6 0 0.58 6 4 0.93 測試結果: 5

bzoj3040: 短路(road)dijkstra

題目 Solution 配對堆優化 dijkstradijkstradijkstra Code #include<bits/stdc++.h> #include<ext/pb_ds/priority_queue.hpp> using na

HDU - 6166:Senior Pan頂點集合短路&二進位制分組

Senior Pan fails in his discrete math exam again. So he asks Master ZKC to give him graph theory problems everyday. The task is simple : ZKC will give

Mining Station on the Sea HDU - 2448費用流 || 短路 && hc

Mining Station on the Sea Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3565

匈牙利算法求大匹配HDU-4185 Oil Skimming

line play bae log classes containe pro include aaaaaa 如下圖:要求最多可以湊成多少對對象 ? 大佬博客:https://blog.csdn.net/cillyb/article/details/55511666 模板:

小數化為簡分式 hdu 1717

hdu 1717 小數化分數 分析: 無限小數可按照小數部分是否迴圈分成兩類:無限迴圈小數和無限不迴圈小數。 無限不迴圈小數不能化分數; 考慮:無限迴圈小數又是如何化分數的呢? 例如:0.325656……×100=32.5656……① 0.325656……×10000

Til the Cows Come Home 短路問題, 模板

題目:https://vjudge.net/problem/POJ-2387  Bessie is out in the field and wants to get back to the barn to get as much sleep as possible befor

演算法作業 短路+記錄全部路徑

思路:採用n*logn的優化迪傑斯特拉演算法,求出最短路,反向建圖以後,在dfs搜尋即可,用set+vector記錄路徑,注意vector的傳遞需要加引用(用string 就不用加引用)。 實現非常簡單,直接看程式碼就行。 #include <bits/stdc++.h> usi

UVA - 816 Abbott's Revenge BFS求短路並列印路徑

The 1999 World Finals Contest included a problem based on a dice maze. At the time the problem was written, the judges were unable to discover t

Newcoder Metropolis多源短路 + Dijkstra堆優化題解

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

【洛谷3953】逛公園短路+記憶化搜尋

點此看題面 大致題意: 有一張有NNN個點和MMM條邊組成的有向圖,若從111號點到NNN號點的最短路徑長度為ddd,問有多少條從111號點到NNN號點的路徑長度不超過d+Kd+Kd+K。若有無數條輸出

短路問題三種演算法與路徑還原演算法

1、Bellman-Ford演算法: 用Bellman-Ford演算法求解單源最短路徑問題,單源最短路徑是指固定一個起點,求它到其他所有點的最短路問題。 struct edge { int from, to, cost; //從頂點from指向頂點to的權值為c

codeforces D. Edge Deletion+短路優先佇列優化

題目連結:http://codeforces.com/contest/1076/problem/D 題目大意: 在一個n個點m條邊的無向圖中起點為1,設初始到達第i個點的最短距離為d[i], 現在要求在圖上刪邊,使剩下的邊等於k條,並讓儘量多的點d[i]與之前相

PAT 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 roads

短路模板dijkstra+鄰接表

#include<iostream> #include<algorithm> #include<stdio.h> #include<stdlib.h>

786B Legacy線段樹 +短路+思維好題

Legacy(傳送門) 題意 給定n顆行星,q次處理,地球位置為s,求解在q次處理後,地球到每一顆行星的位置。 其中q有三種不同的操作: 輸入v,u,w,構建一條從v到u的代價為w的路線 輸入u,l,r,w,構建一條從u到區間[l,r]中任意一

【圖論】單源點短路模板有向圖Dijkstra

#include <cstdio> #include <iostream> #include <cstring> #include <queue> #in

短路HDU2544floyd演算法

題目連結 在每年的校賽裡,所有進入決賽的同學都會獲得一件很漂亮的t-shirt。但是每當我們的工作人員把上百件的衣服從商店運回到賽場的時候,卻是非常累的!所以現在他們想要尋找最短的從商店到賽場的路線,你可以幫助他們嗎?   Input 輸入包括多組資料。每組資料第一行是

【NOIP 2017】逛公園短路+記憶化搜尋

肯定要先跑一次最短路 題目中的k 相當於允許我們走k距離的“冤枉路” 回想之前有些題是如何判斷哪些邊是屬於最短路上的 當dis[now]+edge[u].val==dis[vis] 這條邊就在最短路上 類似的 我們可以得出 dis[now]+edge[u].val-dis[vis]就是這一次走的“冤枉路”的長