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 }
-------------------------------
如有不当之处,还望指出
----------------------------
That's all.