Codeforces Round #408 (Div. 2)-D. Police Stations-多起点bfs

来源:互联网 发布:动物大百科软件下载 编辑:程序博客网 时间:2024/05/21 16:22

还是要加强基本功啊。
多起点bfs,第一次接触。感觉挺好使。
又是勿入图论的阴霾,可能是我图论掌握的不好,一旦涉及见图的,我就开始想会不会是 scc啊,匹配啊什么的。因为我这方面掌握的不好,但是事实是bfs。。我是想到了,但是想的想当复杂,因为bfs是方便记录层数的(dinic算法上的),但是我没有想到多起点一起bfs,最重要的是不理解这道题的意思。
图中开始给定了就是满足条件的图,而只要求删除几条边,而删除边是不会增加距离的(其实是会的,但是我bfs的时候,因为是同时bfs,如果别人记录过了再删除,所以可以保证是较远的,不会增加距离,)。
用vis数组来表示是否被一个点 遍历,如果被了,我就可以删了他了。(因为重复嘛。毛子没钱嘛),然后光荣的记录他。
如果没有,我就暂且慢慢来。正常记录。
也可用一个队列来记录,这样就不会搞迷糊了。
http://codeforces.com/contest/796/problem/D

#include<bits/stdc++.h>using namespace std;/*多点bfs我看了一眼,感觉差不多是bfs,但是应该挺麻烦的,不同的点bfs一次,还要记录他们的关系。如果超过k了在删除,后来看了题解准备接受新的指示,况且现在有点累了。。一看题解竟然是bfs,。更令人崩溃的是k是没有用的,代码思路是把所有的银行都给入队列,如果这个队列bfs到了另一个银行的点,那么就可以把这个边删除了,因为初始条件就可以满足,只是要知道有多少边就好了。*/const int maxn=300007;struct Node{   int to,i;    Node(){};//不能没有空的队列。    Node(int _a,int _b){to=_a;i=_b;};}node[maxn];queue<int>q;vector<Node>G[maxn];int edge[maxn];bool vis[maxn];int bfs(){ int ans=0;   while(!q.empty())   {   int u=q.front();        q.pop();       for(int i=0;i<G[u].size();i++)       {   Node s=G[u][i];           if(edge[s.i]) continue;//已经访问过了。           if(vis[s.to])           {   edge[s.i]=2;               //q.push(s.i);               ans++;               continue;//           }           vis[s.to]=true;           edge[s.i]=1;           q.push(s.to);       }   }    return ans;}int main(){   int m,n,k;    int a,b;    cin>>m>>n>>k;     for(int i=1;i<=n;i++)     {   scanf("%d",&k);         vis[k]=true;        q.push(k);     }    for(int i=1;i<m;i++)    {  scanf("%d%d",&a,&b);        G[a].push_back(Node(b,i));        G[b].push_back(Node(a,i));    }    printf("%d\n",bfs());    for(int i=1;i<m;i++)    {   //printf("%d ",edge[i]);        if(edge[i]==2)        printf("%d ",i);    }    printf("\n");    return 0;}
0 0
原创粉丝点击