UVA 10816 + HDU 1839 Dijstra + 二分 (待研究)

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 }
View Code

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 }
View Code
原文地址:https://www.cnblogs.com/ACMERY/p/4499151.html