HDU #1874 : 暢通工程續
傳送門:http://acm.hdu.edu.cn/showproblem.php?pid=1874
題意:n個點m條邊的無向圖,給定s和t,問從s到t的最短路。
思路:單源最短路,dijkstra即可。
AC代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e18 + 10;
const double _e = 10e-6;
const int maxn = 210;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, z;
char c;
struct node
{
int id;
int dis;
};
int n, m, s, t;
vector<node> G[maxn];
int dis[maxn];
struct cmp
{
bool operator()(node a, node b)
{
return a.dis > b.dis;
}
};
int dij()
{
priority_queue<node, vector<node>, cmp> que;
que.push(node{ s,0 }); dis[s] = 0;
while (!que.empty()) {
node u = que.top(); que.pop();
if (u.id == t)
return u.dis;
for (int i = 0; i < G[u.id].size(); i++) {
node v = G[u.id][i];
if (dis[v.id] == -1 || dis[u.id] + v.dis < dis[v.id]) {
dis[v.id] = dis[u.id] + v.dis;
que.push(node{ v.id,dis[v.id] });
}
}
}
return -1;
}
int main()
{
while (~scanf("%d%d", &n, &m)) {
for (int i = 0; i < n; i++)
G[i].clear();
cl1(dis);
while (m--) {
scanf("%d%d%d", &x, &y, &z);
G[x].push_back(node{ y,z });
G[y].push_back(node{ x,z });
}
scanf("%d%d", &s, &t);
int ans = dij();
printf("%d\n", ans);
}
return 0;
}
HDU #1596 : find the safest road
傳送門:http://acm.hdu.edu.cn/showproblem.php?pid=1596
題意:有n個城市,給出兩兩間的安全度(0~1之間),問從s到t一路上的安全度之積最大爲多少。
思路:由於0~1之間的數相乘只會變小或相等,因此可以用最短路的方法來求最大安全度之積。對於詢問都做一遍dijkstra即可。
AC代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e18 + 10;
const double _e = 10e-6;
const int maxn = 1010;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, z;
char c;
struct node
{
int id;
double dis;
};
int n, m;
double cnt[maxn][maxn];
double dis[maxn];
struct cmp
{
bool operator()(node a, node b)
{
return a.dis < b.dis;
}
};
void dij()
{
priority_queue<node, vector<node>, cmp> que;
for (int i = 1; i <= n; i++)
dis[i] = -1;
dis[x] = 1; que.push(node{ x, dis[x] });
while (!que.empty()) {
node u = que.top(); que.pop();
if (u.id == y) {
if (u.dis == 0)
puts("What a pity!");
else
printf("%.3f\n", u.dis);
return;
}
for (int i = 1; i <= n; i++) {
if (i == u.id)continue;
if (dis[u.id] * cnt[u.id][i] > dis[i]) {
dis[i] = dis[u.id] * cnt[u.id][i];
que.push(node{ i,dis[i] });
}
}
}
}
int main()
{
while (~scanf("%d", &n)) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
scanf("%lf", &cnt[i][j]);
}
scanf("%d", &m);
while (m--) {
scanf("%d%d", &x, &y);
dij();
}
}
return 0;
}
51Nod #1459 : 迷宮遊戲
傳送門:https://www.51nod.com/Challenge/Problem.html#!#problemId=1459
題意:n個房間m條路,每條路有花費的時間t和獲得的得分s,問在花最短時間的前提下,最高得分爲多少。
思路:單源最短路,不過要多記一個得分。
當第一次走到終點時,記錄當前的時間t並繼續進行搜索並更新得分,直到所需的時間>t時才結束搜索。
AC代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e9;
const double _e = 10e-6;
const int maxn = 210;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, z;
struct node
{
int v;
int dis;
};
struct node1
{
int id;
int score;
int dis;
};
vector<node> G[510];
int score[510];
int dis[510];
int n, m, start, endd;
int ans_t, ans_s;
struct cmp
{
bool operator()(node1 a, node1 b)
{
return a.dis > b.dis;
}
};
void dij()
{
priority_queue<node1, vector<node1>, cmp> que;
que.push(node1{ start,score[start],0 });
dis[start] = 0;
while (!que.empty()) {
node1 u = que.top(); que.pop();
if (u.dis > ans_t)return;
if (u.id == endd) {
ans_t = min(ans_t, u.dis);
ans_s = max(ans_s, u.score);
continue;
}
for (int i = 0; i < G[u.id].size(); i++) {
node v = G[u.id][i];
if (dis[v.v] == -1 || u.dis + v.dis <= dis[v.v]) {
dis[v.v] = u.dis + v.dis;
que.push(node1{ v.v,u.score + score[v.v],u.dis + v.dis });
}
}
}
}
int main()
{
while (~scanf("%d%d%d%d", &n, &m, &start, &endd)) {
cl1(dis);ans_s = -1; ans_t = INF;
for (int i = 0; i < n; i++)
scanf("%d", &score[i]);
while (m--) {
scanf("%d%d%d", &x, &y, &z);
G[x].push_back(node{ y,z });
G[y].push_back(node{ x,z });
}
dij();
printf("%d %d\n", ans_t, ans_s);
}
return 0;
}
POJ #2253 : Frogger
傳送門:http://poj.org/problem?id=2253
題意:給出n個平面座標上的點,問所有從點1到達點2的方法中,過程中的最大距離的最小值爲多少。
思路:單源最短路,但這裏最短的不是總體距離而是每次的距離,所以dis數組記錄的東西改變一下就可以了。
(PE的每個case最後要空行)
AC代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e9;
const double _e = 10e-6;
const int maxn = 210;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, z;
struct nn
{
double x, y;
};
int n;
nn a[maxn];
double dis[maxn];
struct node
{
int id;
double dis;
};
struct cmp
{
bool operator()(node a, node b)
{
return a.dis > b.dis;
}
};
double cal(int aa, int bb)
{
return sqrt((a[aa].x - a[bb].x)*(a[aa].x - a[bb].x) + (a[aa].y - a[bb].y)*(a[aa].y - a[bb].y));
}
void dij()
{
priority_queue<node, vector<node>, cmp> que;
for (int i = 1; i <= n; i++) {
dis[i] = cal(1, i);
que.push(node{ i,dis[i] });
}
while (!que.empty()) {
node u = que.top(); que.pop();
if (u.id == 2) {
printf("Frog Distance = %.3f\n", u.dis);
break;
}
for (int i = 1; i <= n; i++) {
if (i == u.id)continue;
double d = cal(u.id, i);
d = max(d, u.dis);
if (d < dis[i]) {
dis[i] = d;
que.push(node{ i,dis[i] });
}
}
}
}
int main()
{
int _ = 1;
while (~scanf("%d", &n)) {
if (n == 0)break;
for (int i = 1; i <= n; i++)
dis[i] = INF;
for (int i = 1; i <= n; i++)
scanf("%lf%lf", &a[i].x, &a[i].y);
printf("Scenario #%d\n", _);
dij();
printf("\n");
_++;
}
return 0;
}
HDU #2680 : Choose the best route
傳送門:http://acm.hdu.edu.cn/showproblem.php?pid=2680
題意:n個點m條邊的有向圖,給定多個起點和一個終點,問從起點到終點最短距離是多少。
思路:把終點看作起點做dijkstra,取起點中距離最近的點就是答案。
AC代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e9 + 10;
const double _e = 10e-6;
const int maxn = 1010;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, z;
char c;
int n, m, endd, w;
vector<int> G[maxn];
int cost[maxn][maxn];
int dis[maxn];
struct node
{
int id;
int dis;
};
struct cmp
{
bool operator()(node a, node b)
{
return a.dis > b.dis;
}
};
void dij()
{
priority_queue<node, vector<node>, cmp> que;
que.push(node{ endd,0 }); dis[endd] = 0;
while (!que.empty()) {
node u = que.top(); que.pop();
for (int i = 0; i < G[u.id].size(); i++) {
int v = G[u.id][i];
if (dis[v] == -1 || dis[v] > u.dis + cost[u.id][v]) {
dis[v] = u.dis + cost[u.id][v];
que.push(node{ v,dis[v] });
}
}
}
}
int main()
{
while (~scanf("%d%d%d", &n, &m, &endd)) {
for (int i = 1; i <= n; i++)
G[i].clear();
cl1(cost); cl1(dis);
while (m--) {
scanf("%d%d%d", &x, &y, &z);
G[y].push_back(x);
if (cost[y][x] == -1 || cost[y][x] > z)
cost[y][x] = z;
}
dij();
int ans = INF;
scanf("%d", &w);
while (w--) {
scanf("%d", &x);
if (dis[x] != -1)
ans = min(ans, dis[x]);
}
if (ans == INF)ans = -1;
printf("%d\n", ans);
}
return 0;
}