齐头并进(51Nod-1649)
題目
在一個叫奧斯汀的城市,有n個小鎮(zhèn)(從1到n編號),這些小鎮(zhèn)通過m條雙向火車鐵軌相連。當(dāng)然某些小鎮(zhèn)之間也有公路相連。為了保證每兩個小鎮(zhèn)之間的人可以方便的相互訪問,市長就在那些沒有鐵軌直接相連的小鎮(zhèn)之間建造了公路。在兩個直接通過公路或者鐵路相連的小鎮(zhèn)之間移動,要花費一個小時的時間。
現(xiàn)在有一輛火車和一輛汽車同時從小鎮(zhèn)1出發(fā)。他們都要前往小鎮(zhèn)n,但是他們中途不能同時停在同一個小鎮(zhèn)(但是可以同時停在小鎮(zhèn)n)。火車只能走鐵路,汽車只能走公路。
現(xiàn)在請來為火車和汽車分別設(shè)計一條線路;所有的公路或者鐵路可以被多次使用。使得火車和汽車盡可能快的到達(dá)小鎮(zhèn)n。即要求他們中最后到達(dá)小鎮(zhèn)n的時間要最短。輸出這個最短時間。(最后火車和汽車可以同時到達(dá)小鎮(zhèn)n,也可以先后到達(dá)。)
輸入
單組測試數(shù)據(jù)。
第一行有兩個整數(shù)n 和 m (2≤n≤400, 0≤m≤n*(n-1)/2) ,表示小鎮(zhèn)的數(shù)目和鐵軌的數(shù)目。
接下來m行,每行有兩個整數(shù)u 和 v,表示u和v之間有一條鐵路。(1≤u,v≤n, u≠v)。
輸入中保證兩個小鎮(zhèn)之間最多有一條鐵路直接相連。
輸出
輸出一個整數(shù),表示答案,如果沒有合法的路線規(guī)劃,輸出-1。
輸入樣例
4 2
1 3
3 4
輸出樣例
2
思路:兩遍?Dijkstra 求兩次的最大值即可
源程序
#include<iostream> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<utility> #include<stack> #include<queue> #include<vector> #include<set> #include<map> #define EPS 1e-9 #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LL long long const int MOD = 1E9+7; const int N = 1000+5; const int dx[] = {-1,1,0,0}; const int dy[] = {0,0,-1,1}; using namespace std;int n,m; struct Edge { //邊int from;//下一條邊的編號int to;//邊到達(dá)的點int dis;//邊的長度Edge(int f,int t,int d) { //構(gòu)造函數(shù)from=f;to=t;dis=d;} };struct HeapNode { //Dijkstra用到的優(yōu)先隊列的結(jié)點int dis;//點到起點距離int u;//點的序號HeapNode(int a,int b) {dis=a;u=b;}bool operator < (const HeapNode &rhs) const {return dis > rhs.dis;} };struct Dijkstra {int n,m;//點數(shù)、邊數(shù),均從0開始vector<Edge> edges;//邊列表vector<int> G[N];//每個結(jié)點出發(fā)的邊的編號bool vis[N];//是否走過int dis[N];//起點s到各點的距離int p[N];//從起點s到i的最短路中的最后一條邊的編號void init(int n) {//初始化this->n = n;for(int i=0; i<n; i++) //清空鄰接表G[i].clear();edges.clear();//清空邊列表}void AddEdge(int from,int to,int diss) {//添加邊,若為無向圖,調(diào)用兩次edges.push_back(Edge(from,to,diss));m=edges.size();//邊的個數(shù)G[from].push_back(m-1);//添加至邊列表}int dijkstra(int s) {//求s到所有點的距離memset(dis,INF,sizeof(dis));memset(vis,false,sizeof(vis));dis[s]=0;priority_queue<HeapNode> Q;//優(yōu)先隊列Q.push(HeapNode(0,s));while(!Q.empty()) {HeapNode x=Q.top();Q.pop();int u=x.u;if(vis[u])//若已被訪問continue;vis[u]=true;//標(biāo)記為已訪問for(int i=0; i<G[u].size(); i++) { //枚舉所有與當(dāng)前點相連的邊Edge &e=edges[G[u][i]];if(dis[e.to] > dis[u]+e.dis) {//更新距離dis[e.to] = dis[u]+e.dis;p[e.to]=G[u][i];Q.push(HeapNode(dis[e.to],e.to));}}}return dis[n];} } DJ; int mp[N][N]; int main() {scanf("%d%d",&n,&m);DJ.init(n);//初始化for(int i=0; i<m; i++) {int x,y;scanf("%d%d",&x,&y);mp[x][y]=1;mp[y][x]=1;//無向圖添邊兩次DJ.AddEdge(x,y,1);DJ.AddEdge(y,x,1);}int res=DJ.dijkstra(1);if(res==INF||m==(n*(n-1))/2)printf("-1\n");else{DJ.init(n);for(int i=1;i<=n;++i){mp[i][i]=1;for(int j=1;j<=n;++j){if(!mp[i][j]){DJ.AddEdge(i,j,1);DJ.AddEdge(j,i,1);}}}if(DJ.dijkstra(1)==INF)printf("-1\n");else{res=max(res,DJ.dijkstra(1));printf("%d\n",res);}}return 0; }?
新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的齐头并进(51Nod-1649)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 元素(HYSBZ-2460)
- 下一篇: 理论基础 —— 索引 —— 稠密索引