UVA
题意:两个绿洲之间是沙漠,沙漠的温度不同,告诉起点,终点,求使得从起点到终点的最高温度最小的路径,如果有多条,输出长度最短的路径;
思路:用最小费用(最短路径)最大流(最小温度)也能搞吧,但因为题意是看着博客做的,不小心看到了他的思路,就自己实现了一遍,二分温度,假设当前温度为x,求保证最大温度为x的情况下的最短路;打印路径就是递归打印。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cstring> 6 #include <cmath> 7 #include <vector> 8 #include <queue> 9 #include <stack> 10 #include <set> 11 #include <map> 12 #define oo 1e9 13 #define repu(i, a, b) for(int i = (a); i < (b); i++) 14 using namespace std; 15 typedef long long LL; 16 const int maxn=2200; 17 const int INF=0x3f3f3f3f; 18 int rode[maxn]; 19 int st,ed; 20 struct Edge 21 { 22 int u, v; 23 double t, d; 24 Edge(int u, int v, double t, double d):u(u), v(v), t(t), d(d) {} 25 }; 26 struct qnode 27 { 28 int u; 29 double d; 30 qnode(int u, double d):u(u), d(d) {} 31 bool operator < (const qnode a)const 32 { 33 return d > a.d; 34 } 35 }; 36 struct Dijkstra 37 { 38 int n; 39 vector<int> G[maxn]; 40 vector<Edge> edge; 41 double d[maxn]; 42 bool vis[maxn]; 43 void init(int n) 44 { 45 this->n=n; 46 for(int i=0; i<=n; i++) 47 { 48 G[i].clear(); 49 vis[i]=0; 50 d[i]=INF; 51 } 52 edge.clear(); 53 } 54 void AddEdge(int u, int v, double t, double d) 55 { 56 G[u].push_back(edge.size()); 57 edge.push_back(Edge(u, v, t, d)); 58 } 59 bool dijkstra(double cur) 60 { 61 memset(rode, -1, sizeof rode); 62 memset(vis, 0, sizeof vis); 63 repu(i,0,n+1) 64 d[i] = oo; 65 priority_queue<qnode> q; 66 d[st]=0.00; 67 q.push(qnode(st, 0)); 68 while(!q.empty()) 69 { 70 qnode x=q.top(); 71 q.pop(); 72 if(vis[x.u]) 73 continue ; 74 vis[x.u]=true; 75 if(x.u == ed) 76 return true; 77 for(int i=0; i<G[x.u].size(); i++) 78 { 79 Edge& e=edge[G[x.u][i]]; 80 if(e.t <= cur&& d[e.v]>d[x.u]+e.d) 81 { 82 ///加条件,保证最大的温度是e.t 83 d[e.v]=d[x.u]+e.d; 84 rode[e.v]=x.u;///保存路径 85 q.push(qnode(e.v, d[e.v])); 86 } 87 } 88 } 89 return d[ed] < oo; 90 } 91 } dij; 92 void printroad(int x) 93 { 94 if(x==st) 95 { 96 printf("%d", x); 97 return ; 98 } 99 printroad(rode[x]); 100 printf(" %d", x); 101 } 102 int main() 103 { 104 int n,m; 105 while(~scanf("%d%d",&m,&n)) 106 { 107 dij.init(m); 108 scanf("%d%d",&st,&ed); 109 int u,v; 110 double c,w; 111 vector<double> se; 112 repu(i,0,n) 113 { 114 scanf("%d%d%lf%lf",&u,&v,&c,&w); 115 se.push_back(c); 116 dij.AddEdge(u, v, c, w); 117 dij.AddEdge(v, u, c, w); 118 } 119 sort(se.begin(),se.end());///按照温度排序进行二分 120 int L = 0, R = unique(se.begin(),se.end())- se.begin()-1; 121 int mid; 122 while(L<R) 123 { 124 mid=(L+R)/2; 125 if(dij.dijkstra(se[mid])) 126 R=mid;///如果存在就找更小的温度 127 else L=mid+1; 128 } 129 dij.dijkstra(se[R]);///找到的R就是最终的条件 130 printroad(ed); 131 printf(" %.1lf %.1lf ", dij.d[ed], se[R]); 132 } 133 return 0; 134 }
HDU
题意:起点1,终点m,每条道路都有一个最大容量,以及通过的时间,求在时间T内能过的最大的容量;
思路:得用最大流吧,但是可能数据水,跟上一题一样的思路居然也能过。
注意:说代码的话,跟上一题完全一样,除了二分,但我被坑的一点就是二分,L跟R赋值的时候没改掉,就debug其他的地方,花费了不少的时间;
按照从小到大的顺序排好后,进行二分,注意mid = (l + r + 1)/ 2;符合的 l = mid;否则r = mid -1;(这是找越大的越好)---mid为啥+1母鸡啊
按照从小到大的顺序排好后,进行二分,注意mid = (l + r )/ 2;符合的 l = mid - 1;否则r = mid ;(这是找越小的越好)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cstring> 6 #include <cmath> 7 #include <vector> 8 #include <queue> 9 #include <stack> 10 #include <set> 11 #include <map> 12 #define repu(i, a, b) for(int i = (a); i < (b); i++) 13 using namespace std; 14 typedef long long LL; 15 const int maxn=10010; 16 const int INF=0x3f3f3f3f; 17 int rode[maxn]; 18 int st,ed,T; 19 struct Edge 20 { 21 int u, v; 22 int t, d; 23 Edge(int u, int v, int t, int d):u(u), v(v), t(t), d(d) {} 24 }; 25 struct qnode 26 { 27 int u; 28 int d; 29 qnode(int u, int d):u(u), d(d) {} 30 bool operator < (const qnode a)const 31 { 32 return d > a.d; 33 } 34 }; 35 struct Dijkstra 36 { 37 int n; 38 vector<int> G[maxn]; 39 vector<Edge> edge; 40 int d[maxn]; 41 bool vis[maxn]; 42 void init(int n) 43 { 44 this->n=n; 45 for(int i=0; i<=n; i++) 46 { 47 G[i].clear(); 48 vis[i]=0; 49 d[i]=INF; 50 } 51 edge.clear(); 52 } 53 void AddEdge(int u, int v, int t, int d) 54 { 55 G[u].push_back(edge.size()); 56 edge.push_back(Edge(u, v, t, d)); 57 } 58 int dijkstra(int cur) 59 { 60 memset(vis, 0, sizeof vis); 61 repu(i,1,n+1) 62 d[i]=i==1?0:INF; 63 priority_queue<qnode> q; 64 d[st]=0; 65 q.push(qnode(st, 0)); 66 while(!q.empty()) 67 { 68 qnode x=q.top(); 69 q.pop(); 70 if(vis[x.u]) 71 continue ; 72 vis[x.u]=true; 73 if(x.u == ed) 74 return d[ed] <= T; 75 for(int i=0; i<G[x.u].size(); i++) 76 { 77 Edge& e=edge[G[x.u][i]]; 78 if(e.t >= cur && d[e.v] > d[x.u]+e.d) 79 { 80 ///加条件,保证最小的容量是cur 81 d[e.v]=d[x.u]+e.d; 82 q.push(qnode(e.v, d[e.v])); 83 } 84 } 85 } 86 return d[ed] <= T; 87 } 88 } dij; 89 int main() 90 { 91 int n,m,I; 92 scanf("%d",&I); 93 while(I--) 94 { 95 scanf("%d%d%d",&m,&n,&T); 96 dij.init(m); 97 st = 1; 98 ed = m; 99 int u,v; 100 int c,w; 101 vector<int> se; 102 repu(i,0,n) 103 { 104 scanf("%d%d%d%d",&u,&v,&c,&w); 105 se.push_back(c); 106 dij.AddEdge(u, v, c, w); 107 dij.AddEdge(v, u, c, w); 108 } 109 sort(se.begin(),se.end());///按照容量排序进行二分 110 int L = 0, R = unique(se.begin(),se.end())- se.begin()-1; 111 int mid; 112 while(L < R)///居然在这里栽坑了 113 { 114 mid=(L + R + 1)/2; 115 if(dij.dijkstra(se[mid])) 116 L=mid;///如果存在就找更大的容量 117 else R=mid-1; 118 } 119 printf("%d ", se[L]); 120 } 121 return 0; 122 }