zoukankan      html  css  js  c++  java
  • P1948 [USACO08JAN]电话线Telephone Lines

    ------------------------------

    这道题就是我们的sb比赛第四题

    -----------------------------

    这道题吧,还是很有意思的,需要用到二分,不过用bfs也行(暴力出奇迹)

    ------------------------------

    并且深刻让我感受到了做题时,重构代码的恶心

    有时候就是写错了一个字母,但是怎么找还找不出来

    --------------------------------

    题目链接:Miku

    -------------------------------

    这道题就是BFS+可能是记忆化?+图论

    中心就是记录当前点,用的边数,和最小值,而答案用mink数组储存

    因为搜索的原因,最后还要扫一遍

    ------------------------------

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<cmath>
     8 using namespace std;
     9 //queue<E> q;
    10 int max(int x,int y)
    11 {
    12     if(x>y)
    13     return x;
    14     else
    15     return y;
    16 }
    17 struct E{
    18     int to;
    19     int dis;
    20     int next;
    21 }e[10000*3+666];
    22 int tail,headd;//指针 
    23 struct bfs{
    24 int now;
    25 int nowdis;
    26 int nowk; 
    27 }q[1000000+676];//队列 
    28 bfs qu[1000000+676]; 
    29 int head[1000+676];
    30 int n,m,k;
    31 int mink[1005][1005];
    32 int p;
    33 int x,y,z;
    34 void add(int f,int to,int v){
    35     p++;
    36     e[p].next=head[f];
    37     e[p].to=to;
    38     e[p].dis=v;
    39     head[f]=p;
    40     return ;//插入 
    41 }
    42 inline void in(int now,int k,int dis){
    43     qu[tail].now=now;
    44     qu[tail].nowdis=dis;
    45     qu[tail].nowk=k;
    46     tail++;
    47     if(tail==1000000+666) tail=0;//循环队列 
    48     return ;
    49 }
    50 void bfss(){
    51       while(headd!=tail)
    52         {
    53             int now,nowk,nowdis;
    54             now=qu[headd].now;
    55             nowk=qu[headd].nowk;
    56             nowdis=qu[headd].nowdis;//取出队首 
    57             headd++;
    58             if(headd==1000000+666) headd=0;//循环 
    59             for(int i=head[now];i;i=e[i].next)
    60             {
    61                int to=e[i].to;//遍历 
    62                //这两个都自带剪枝
    63                //就是如果当前值比mink的费用大,就没必要搜索了 
    64             if(max(nowdis,e[i].dis)<mink[to][nowk])//这是没用免费边 
    65             {//max解决nowdis为零时的情况 
    66                 mink[to][nowk]=max(nowdis,e[i].dis);
    67                 in(to,nowk,max(nowdis,e[i].dis));
    68             }//如果用了免费,那么就有可能是0费,所以不用max 
    69             if(nowdis<mink[to][nowk+1]&&nowk<k)//这是使用了免费边的情况 
    70             {
    71                 mink[to][nowk+1]=nowdis;
    72                 in(to,nowk+1,nowdis);
    73             }
    74         }
    75 }
    76 }
    77 int main(){
    78     cin>>n>>m>>k;
    79     for(int i=1;i<=m;++i)
    80     {
    81         cin>>x>>y>>z;
    82         add(x,y,z);
    83         add(y,x,z);
    84     }
    85     in(1,0,0);//初始状态 
    86     memset(mink,0x3f,sizeof(mink));
    87     for(int i=0;i<=k;++i)
    88     mink[1][i]=0;//初始化,起始费用为0 
    89       bfss(); 
    90     int ans=0x7fffffff;
    91     for(int i=0;i<=k;++i)
    92     ans=min(ans,mink[n][i]);//扫一遍答案(因为这是搜索 
    93     if(ans==0x3f3f3f3f) cout<<"-1"<<endl;
    94     else
    95     cout<<ans<<endl;
    96     return 0;
    97 }
    AC

    -------------------------------

    如有不当之处,还望指出

    ----------------------------

    That's all.

  • 相关阅读:
    第 01 组 Alpha 事后诸葛亮
    第 01 组 Alpha 冲刺(4/4)
    第 01 组 Alpha 冲刺(3/4)
    第 01 组 Alpha 冲刺(2/4)
    第 01 组 Alpha 冲刺(1/4)
    学习日志-2021.11.08
    论文阅读-2021.11.06
    学习日志-2021.10.25
    学习日志-2021.10.24
    学习日志-2021.10.18
  • 原文地址:https://www.cnblogs.com/For-Miku/p/10961958.html
Copyright © 2011-2022 走看看