• EOJ-2104 小强过桥


    http://acm.cs.ecnu.edu.cn/problem.php?problemid=2104

    题意:给出n个节点之间路径的载重量,求出从s点到t点的可行的最大载重量。

    解法:n的数据量10^6,只能用邻接表存储,二分枚举最大载重量,用BFS遍历图判断是否合理,直到得到最优解。

     1 #include<map>
     2 #include<set>
     3 #include<list>
     4 #include<cmath>
     5 #include<ctime>
     6 #include<queue>
     7 #include<stack>
     8 #include<cctype>
     9 #include<cstdio>
    10 #include<string>
    11 #include<vector>
    12 #include<cstdlib>
    13 #include<cstring>
    14 #include<iostream>
    15 #include<algorithm>
    16 using namespace std;
    17 const int maxn=1000005;
    18 struct node{
    19     int v,w,next;
    20 }edge[maxn];                    //存储边邻接表
    21 int head[maxn];                    //头指针
    22 int Q[maxn];                    //BFS所用队列
    23 bool mark[maxn];                //BFS用标记
    24 int id,n;                        //边的编号,节点个数
    25 void add(int u,int v,int w){
    26     edge[id].v=v;
    27     edge[id].w=w;
    28     edge[id].next=head[u];
    29     head[u]=id++;
    30 }
    31 bool bfs(int s,int t,int weight){
    32     memset(mark,0,sizeof(mark));
    33     int f=0,r=0;
    34     Q[r++]=s;
    35     mark[s]=1;
    36     while(f<r){
    37         int tp=Q[f++];
    38         for(int i=head[tp];i!=-1;i=edge[i].next){
    39             int V=edge[i].v;
    40             if(edge[i].w>=weight && mark[V]==0){    //将满足条件的顶点加入队
    41                 if(V==t)return true;                //到达终点
    42                 mark[V]=1;
    43                 Q[r++]=V;
    44             }
    45         }
    46     }
    47     return false;
    48 }            
    49 int main(){
    50     int m;
    51     while(~scanf("%d%d",&n,&m)){
    52         int l=2000000001,r=0;
    53         id=1;
    54         memset(head,-1,sizeof(head));
    55         while(m--){
    56             int u,v,w;
    57             scanf("%d%d%d",&u,&v,&w);
    58             add(u,v,w);                    //双向边
    59             add(v,u,w);    
    60             l=min(l,w);                    //记录最大上限与下限
    61             r=max(r,w);
    62         }
    63         int s,t;
    64         scanf("%d%d",&s,&t);
    65         int ans;
    66         while(l<=r){                    //二分枚举载重
    67             m=(l+r)/2;
    68             if(bfs(s,t,m)){ ans=m;l=m+1;}
    69             else r=m-1;
    70         }
    71         printf("%d
    ",ans);
    72     }
    73     return 0;
    74 }
    View Code

     我再贴一个用stl写的

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cctype>
     5 #include <vector>
     6 #include <queue>
     7 #include <algorithm>
     8 using namespace std;
     9  
    10 const int MAXN = 1000005;
    11 
    12 int n, m, s, t;
    13 int mark[MAXN];
    14 
    15 struct node
    16 {
    17     int v, w;
    18 };
    19 
    20 vector<node>edge[MAXN];
    21 
    22 void add(int u, int v, int w)
    23 {
    24     node p;
    25     p.v = v;
    26     p.w = w;
    27     edge[u].push_back(p);
    28 }
    29 
    30 bool bfs(int s, int t, int tmp)
    31 {
    32     memset(mark, 0, sizeof(mark));
    33     queue<int>q;
    34     q.push(s);
    35     mark[s] = 1;
    36     while (!q.empty())
    37     {
    38         int cur = q.front();
    39         q.pop();
    40         for (int i = 0; i < edge[cur].size(); i++)
    41         {
    42             int next = edge[cur][i].v;
    43             int temp = edge[cur][i].w;
    44             if (edge[cur][i].w >= tmp && mark[next] == 0)
    45             {
    46                 if (next == t) return true;
    47                 mark[next] = 1;
    48                 q.push(next);
    49             }
    50         }
    51     }
    52     return false;
    53 }
    54 
    55 int main()
    56 {
    57     
    58     while (cin >> n >> m)
    59     {
    60         int l = 2000000001, r = 0;
    61         for (int i = 0; i < MAXN; i++)
    62             edge[i].clear();
    63         while (m--)
    64         {
    65             int u, v, w;
    66             scanf("%d%d%d", &u, &v, &w);
    67             add(u, v, w);
    68             add(v, u, w);
    69             l = min(w, l);
    70             r = max(w, r);
    71         }
    72         cin >> s >> t;
    73         int ans;
    74         while (l <= r)
    75         {
    76             int tmp = (r + l + 1)/2;    
    77             if (bfs(s, t, tmp))
    78             {
    79                 l = tmp + 1;
    80                 ans = tmp;            
    81             }
    82             else
    83                 r = tmp - 1;
    84         }
    85         printf("%d
    ", ans);
    86     }
    87     return 0;
    88 }
    View Code
  • 相关阅读:
    Java正则表达式的使用
    萤火虫小巷2(看完了)
    第七章--Java基础类库--与用户的互动
    Android界面编程--使用活动条(ActionBar)--通过ActionBar菜单改变TextView的字体和颜色
    电影:换肤(Replace)
    Android界面编程--使用活动条(ActionBar)
    萤火虫小巷1
    大三下半学期(3月4日定下的学习计划)
    12月17日问题
    JQuery 分页显示jquery-pager-1.0.js
  • 原文地址:https://www.cnblogs.com/KimKyeYu/p/3182700.html
Copyright © 2020-2023  润新知