POJ3268 Silver Cow Party【Dijkstra演算法+思維】
Silver Cow Party
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 30185 | Accepted: 13703 |
Description
One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A total of M (1 ≤ M ≤ 100,000) unidirectional (one-way roads connects pairs of farms; road i requires Ti (1 ≤ Ti ≤ 100) units of time to traverse.
Each cow must walk to the party and, when the party is over, return to her farm. Each cow is lazy and thus picks an optimal route with the shortest time. A cow's return route might be different from her original route to the party since roads are one-way.
Of all the cows, what is the longest amount of time a cow must spend walking to the party and back?
Input
Line 1: Three space-separated integers, respectively: N, M, and X
Lines 2..M+1: Line i+1 describes road i with three space-separated integers: Ai, Bi, and Ti. The described road runs from farm Ai to farm Bi, requiring Titime units to traverse.
Output
Line 1: One integer: the maximum of time any one cow must walk.
Sample Input
4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3
Sample Output
10
Hint
Cow 4 proceeds directly to the party (3 units) and returns via farms 1 and 3 (7 units), for a total of 10 time units.
Source
問題描述:有m條單向邊連線著 n個農場(從1開始編號),每個農場都會派出一個奶牛去X號農場參加派對,派對結束後再返回各自的農場。求奶牛們的最短路徑的最大值。
解題思路:奶牛i需要的最短時間=i到x的最短時間+x到i的最短時間。前者好求,可以使用dijkstra演算法,後者要先將鄰接矩陣轉置再執行最短路演算法:u(u != x)到x的最短路為<u,v1>,<v1,v2>,<v2,v3>,...,<vi, x>,這條路徑在轉置鄰接矩陣後變成<x,vi>,...,<v3,v2>,<v2, v1>,<v1,u>.於是,在轉置鄰接矩陣後,執行最短路演算法求出x到u的最短路<x,vi>,...,<v3,v2>,<v2, v1>,<v1,u>即可得到轉置前u到x的最短路。
AC的C++程式碼:
#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;
const int INF=((unsigned int)(-1)>>1);//2^31-1
const int N=1005;
struct Node{//表示結點的結構體
int u,cost;//表示此刻源點到結點u的最短路徑為cost
Node(){}
Node(int u,int cost):u(u),cost(cost){}
bool operator<(const Node &a)const//按照此刻源點到結點v的最短距離從小到大排序
{
return cost>a.cost;//由於使用優先佇列故過載為大於含義
}
};
int g[N][N];//鄰接矩陣
int rg[N][N];
int dist[N];//記錄源點到個結點的最短路徑
int ans[N];
bool vis[N];//記錄源點到結點i的最短路徑是否已經找到
void dijkstra(int s,int n)//源點編號是s,共有n個結點
{
priority_queue<Node>q;
for(int i=1;i<=n;i++){//初始化
dist[i]=INF;
vis[i]=false;
}
dist[s]=0;//源點到源點的距離是0
q.push(Node(s,0));
while(!q.empty()){
Node e=q.top();
q.pop();
int u=e.u;//此結點的最短路以找到
if(!vis[u]){
vis[u]=true;
for(int i=1;i<=n;i++){
if(g[u][i]==INF)
continue;
int temp=dist[u]+g[u][i];
if(temp<dist[i]){
dist[i]=temp;
q.push(Node(i,temp));
}
}
}
}
}
int main()
{
int n,m,x,a,b,t;
while(scanf("%d%d%d",&n,&m,&x)!=EOF){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
g[i][j]=(i==j)?0:INF;
while(m--){
scanf("%d%d%d",&a,&b,&t);
if(g[a][b]>t)
g[a][b]=t;
}
//求x到各個點的最短路
dijkstra(x,n);
memcpy(ans,dist,sizeof(dist));//儲存x到各個點的最短路
//轉置g
memcpy(rg,g,sizeof(g));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
g[i][j]=rg[j][i];
//求各個點到x的最短路
dijkstra(x,n);
int res=0;
for(int i=1;i<=n;i++){
ans[i]+=dist[i];
if(ans[i]<INF&&ans[i]>res)
res=ans[i];
}
printf("%d\n",res);
}
return 0;
}
相關文章
- P8271 [USACO22OPEN] COW Operations S (思維)
- Dijkstra演算法演算法
- 思維體系---技術思維、業務資料思維、產品思維、複合思維
- 演算法基礎思維導圖演算法
- 對演算法思維提升的思考演算法
- 求職思維和招聘思維求職
- 淺析工具思維、產品思維、品牌思維與定位
- 最短路dijkstra演算法演算法
- 貪心演算法Dijkstra演算法
- 最短路 - Dijkstra 演算法演算法
- [演算法]挑戰你思維中的牆演算法
- 最短路演算法之:Dijkstra 演算法演算法
- JAVA實現DIJKSTRA演算法Java演算法
- 黑客思維黑客
- 思維模式模式
- 框架思維框架
- 【JAVA演算法】圖論演算法 -- Dijkstra演算法Java演算法圖論
- 組合思維與繼承思維的不同繼承
- 最短路徑之Dijkstra演算法演算法
- Dijkstra 演算法的手動分析演算法
- 最短路-樸素版Dijkstra演算法&堆優化版的Dijkstra演算法優化
- 演算法設計幾個經典思維題目演算法
- 最短路徑——Dijkstra演算法和Floyd演算法演算法
- 最短路徑—Dijkstra演算法和Floyd演算法演算法
- 模型思維(01)模型
- 計算思維
- 最短路徑問題 (dijkstra演算法)演算法
- 單源最短路徑-Dijkstra演算法演算法
- 單源最短路徑 -- Dijkstra演算法演算法
- dijkstra最短路演算法模板(雙源)演算法
- Dijkstra演算法及正確性分析演算法
- 《計算思維史話》思維導圖——持續更新
- 創新思維框架:第一原則思維 - Neil Kakkar框架
- 你是整體思維還是分析思維? - kentbeck
- 提升思維邏輯—SimpleMind Pro(思維導圖) for Mac/winMac
- 什麼是產品思維和專案思維? - Shreyas
- 英語思維與物件導向分析思維的關係物件
- 思維之道 --讀《質量.軟體.管理 系統思維》(2)