[USACO08JAN]电话线Telephone Lines(分层图)/洛谷P1948

这道题其实是分层图,但和裸的分层图不太一样。因为它只要求路径总权值为路径上最大一条路径的权值,但仔细考虑,这同时也满足一个贪心的性质,那就是当你每次用路径总权值小的方案来更新,那么可以保证新的路径权值尽量小。

所以这道题在不删边的情况下可以使用Dij来跑,而删边权的情况就是分层图。

所以就拿分层图来搞好了^_^。

由于这个数据p和k都比较大,所以直接建k+1层图是要爆的,而k+1层图边都一样,我们就用dis[层数(0-k)]来表示。

具体的就是每次Dij转移是要分两种情况:

1.在原层跑,也就是说,在这层中用Dij
2.若下一层边的另一端不够优秀,就用这一层来直接更新,当然就是把这一端的点的解直接复制

大概就是这样了

 1 #include<queue>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 struct tmp{
 7   int no;
 8   int ler;
 9   int dis;
10   bool friend operator < (tmp x,tmp y)
11   {
12     return x.dis>y.dis;
13   }
14 };
15 struct pnt{
16   int no;
17   int hd;
18   int dis[1005];
19   bool vis[1005];
20 }p[1005];
21 struct ent{
22   int twd;
23   int lst;
24   int vls;
25 }e[50000];
26 int n,m,d;
27 int cnt;
28 priority_queue<tmp>Q;
29 void ade(int f,int t,int v)
30 {
31   cnt++;
32   e[cnt].twd=t;
33   e[cnt].lst=p[f].hd;
34     p[f].hd=cnt;
35     e[cnt].vls=v;
36 }
37 int main()
38 {
39     scanf("%d%d%d",&n,&m,&d);
40     for(int i=1;i<=n;i++)
41     {
42         p[i].no=i;
43         for(int j=0;j<=d;j++)
44         {
45             p[i].dis[j]=0x3f3f3f3f;
46         }
47     }
48     p[1].dis[0]=0;
49     for(int i=1;i<=m;i++)
50     {
51         int a,b,c;
52         scanf("%d%d%d",&a,&b,&c);
53         ade(a,b,c);
54         ade(b,a,c);
55     }
56     tmp x;
57     x.no=1;
58     x.ler=0;
59     x.dis=0;
60     Q.push(x);
61     while(!Q.empty())
62     {
63         x=Q.top();
64         Q.pop();
65         int nw=x.no;
66         int t=x.ler;
67         if(x.no==n&&x.ler==d)
68         {
69             printf("%d\n",x.dis);
70             return 0;
71         }
72         if(p[nw].vis[t])continue;
73         p[nw].vis[t]=true;
74         for(int i=p[nw].hd;i;i=e[i].lst)
75         {
76             int to=e[i].twd;
77             if(p[to].dis[t]>max(p[nw].dis[t],e[i].vls))
78             {
79                 p[to].dis[t]=max(p[nw].dis[t],e[i].vls);
80                 x=(tmp){to,t,p[to].dis[t]};
81                 Q.push(x);
82             }
83             if(p[to].dis[t+1]>p[nw].dis[t]&&t<d)
84             {
85                 p[to].dis[t+1]=p[nw].dis[t];
86                 x=(tmp){to,t+1,p[to].dis[t+1]};
87                 Q.push(x);
88             }
89         }
90     }
91     printf("-1\n");
92     return 0;
93 }
94 
95 telephone line

 

其实,这道题还可以二分来搞,我就不赘述了主要是我太懒了

posted @ 2018-07-27 10:57  Unstoppable728  阅读(262)  评论(0编辑  收藏  举报