首页 > 其他 > 详细

POJ_3662_Telephone_Lines

时间:2016-04-23 13:30:03      阅读:246      评论:0      收藏:0      [点我收藏+]

描述


http://poj.org/problem?id=3662

给一张图,要将1与n连起来.可以有k条边免费,其他边付费,付费的值为所有自费边中最大的值.求最小付费.

分析


可以假定一个付费值m,所有<=m的都自己付费,>m的免费,然后使>m的边数a尽可能小,看是否可以使得a<=k.这里用二分即可.

统计a的最小值时,我们考虑:边分为免费边和自费边,要让免费边数量尽可能小,就把免费边赋值为1,自费边赋值为0,跑最短路,最后d[n]就是最少经过的免费边数量a.

另外,二分的标准如果是0~maxl的话就太大了,我们可以把每一条边的值存在f数组中,然后二分f[0]~f[p],这样会小很多.

注意:

1.如果自费最大费用(不用免费的了),还是不能成功,就输出-1.

技术分享
 1 #include<cstdio>
 2 #include<vector>
 3 #include<queue>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn=1005,maxp=10005,INF=1<<27;
 8 struct node
 9 {
10     int to,w;
11     node(){}
12     node(int a,int b) : to(a),w(b){}
13     bool operator < (const node &a) const { return a.w>w; }
14 };
15 vector <node> g[maxn];
16 int n,p,k;
17 int d[maxn],f[maxp];
18 
19 bool Dijkstra(int m)
20 {
21     for(int i=1;i<=n;i++) d[i]=INF;
22     d[1]=0;
23     priority_queue <node> q;
24     q.push(node(1,0));
25     while(!q.empty())
26     {
27         int x=q.top().to;q.pop();
28         for(int i=0;i<g[x].size();i++)
29         {
30             int y=g[x][i].to,dxy=g[x][i].w;
31             dxy=dxy>m ? 1 : 0;
32             if(d[y]>d[x]+dxy)
33             {
34                 d[y]=d[x]+dxy;
35                 q.push(node(y,d[y]));
36             }
37         }
38     }
39     return (d[n]<=k);
40 }
41 
42 void solve()
43 {
44     if(!Dijkstra(f[p])) { printf("-1\n"); return; }
45     int l=0,r=p;
46     while(l<r)
47     {
48         int m=l+(r-l)/2;
49         if(Dijkstra(f[m])) r=m;
50         else l=m+1;
51     }
52     printf("%d\n",f[l]);
53 }
54 
55 void init()
56 {
57     scanf("%d%d%d",&n,&p,&k);
58     for(int i=1;i<=p;i++)
59     {
60         int a,b,c;
61         scanf("%d%d%d",&a,&b,&c);
62         g[a].push_back(node(b,c));
63         g[b].push_back(node(a,c));
64         f[i]=c;
65     }
66     sort(f+1,f+1+p);
67 }
68 
69 int main()
70 {
71 #ifndef ONLINE_JUDGE
72     freopen("phone.in","r",stdin);
73     freopen("phone.out","w",stdout);
74 #endif
75     init();
76     solve();
77 #ifndef ONLINE_JUDGE
78     fclose(stdin);
79     fclose(stdout);
80 #endif
81     return 0;
82 }
83     
Dijkstra
技术分享
 1 #include<cstdio>
 2 #include<vector>
 3 #include<queue>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn=1005,maxp=10005,INF=1<<27;
 8 struct node
 9 {
10     int to,w;
11     node(){}
12     node(int a,int b) : to(a),w(b){}
13 };
14 vector <node> g[maxn];
15 int n,p,k;
16 int d[maxn],f[maxp];
17 bool vis[maxn];
18 
19 bool Spfa(int m)
20 {
21     for(int i=1;i<=n;i++) { d[i]=INF; vis[i]=false; }
22     d[1]=0; vis[1]=true;
23     queue <int> q;
24     q.push(1);
25     while(!q.empty())
26     {
27         int x=q.front();
28         q.pop();
29         vis[x]=false;
30         for(int i=0;i<g[x].size();i++)
31         {
32             int y=g[x][i].to,dxy=g[x][i].w;
33             dxy=dxy>m ? 1 : 0;
34             if(d[y]>d[x]+dxy)
35             {
36                 d[y]=d[x]+dxy;
37                 if(!vis[y])
38                 {
39                     vis[y]=true;
40                     q.push(y);
41                 }
42             }
43         }
44     }
45     return (d[n]<=k);
46 }
47 
48 void solve()
49 {
50     if(!Spfa(f[p])) { printf("-1\n"); return; }
51     int l=0,r=p;
52     while(l<r)
53     {
54         int m=l+(r-l)/2;
55         if(Spfa(f[m])) r=m;
56         else l=m+1;
57     }
58     printf("%d\n",f[l]);
59 }
60 
61 void init()
62 {
63     scanf("%d%d%d",&n,&p,&k);
64     for(int i=1;i<=p;i++)
65     {
66         int a,b,c;
67         scanf("%d%d%d",&a,&b,&c);
68         g[a].push_back(node(b,c));
69         g[b].push_back(node(a,c));
70         f[i]=c;
71     }
72     sort(f+1,f+1+p);
73 }
74 
75 int main()
76 {
77 #ifndef ONLINE_JUDGE
78     freopen("phone.in","r",stdin);
79     freopen("phone.out","w",stdout);
80 #endif
81     init();
82     solve();
83 #ifndef ONLINE_JUDGE
84     fclose(stdin);
85     fclose(stdout);
86 #endif
87     return 0;
88 }
89     
Spfa

 

POJ_3662_Telephone_Lines

原文:http://www.cnblogs.com/Sunnie69/p/5424340.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!