1013. Battle Over Cities (25)

来源:互联网 发布:http代理默认端口 编辑:程序博客网 时间:2024/05/29 19:30

思路:

通过 并查集基本操作(GetPre Merge)求图的连通分量个数-1 即为所要修建的数量

#include<iostream>#include<fstream>using namespace std;const int Size=1010;struct node{    int x, y;}Nodes[Size*Size];int Pre[Size];void Init(int N){    for(int i=1; i<=N; i++)        Pre[i]=i;}int GetPre(int a){    if(Pre[a]!=a)        Pre[a]=GetPre(Pre[a]);    return Pre[a];}void Merge(int a, int b){    int p1=GetPre(a);    int p2=GetPre(b);    if(p1!=p2)        Pre[p1]=p2;}int main(){    //ifstream cin("test.txt");    int N, M, K;    cin>>N>>M>>K;    for(int i=0; i<M; i++)    {        cin>>Nodes[i].x>>Nodes[i].y;    }    while(K--)    {        int num;        cin>>num;        Init(N);        for(int i=0; i<M; i++)        {            if(Nodes[i].x==num||Nodes[i].y==num)                continue;            Merge(Nodes[i].x,Nodes[i].y);        }        int ans=0;        for(int i=1; i<=N; i++)        {            if(i==num)                continue;            if(Pre[i]==i)                ans++;        }        cout<<ans-1<<endl;    }    return 0;}

DFS版本

#include<iostream>#include<fstream>#include<cstring>using namespace std;const int Size=1010;int edge[Size][Size];int visited[Size];int K, M, N;void dfs(int i){    visited[i]=1;    for(int j=1; j<=N; j++)    {        if(!visited[j]&&edge[i][j])            dfs(j);    }}int main(){    //ifstream cin("test.txt");    memset(edge, 0, sizeof(edge));    cin>>N>>M>>K;    for(int i=0,a, b; i<M; i++)    {        cin>>a>>b;        edge[a][b]=edge[b][a]=1;    }    int tmp;    while(K--)    {        cin>>tmp;        memset(visited, 0, sizeof(visited));        int ans=0;        visited[tmp]=1;        for(int i=1; i<=N; i++)        {            if(!visited[i])            {                dfs(i);                ans++;            }        }        cout<<ans-1<<endl;    }    return 0;}

BFS : 最后一个测试点超时 其他测试点正确 目前想不到还有什么剪枝了···

#include<iostream>#include<cstring>#include<queue>using namespace std;const int Size=1010;int edge[Size][Size];int K, M, N;int visited[Size];int main(){    memset(edge,0,sizeof(edge));    cin>>N>>M>>K;    for(int i=0,a,b; i<M; i++)    {        cin>>a>>b;        edge[a][b]=edge[b][a]=1;    }    int tmp;    queue<int>que;    while(K--)    {        cin>>tmp;        memset(visited,0,sizeof(visited));        int ans=0;        visited[tmp]=1;        for(int i=1; i<=N; i++)        {            if(!visited[i])            {                que.push(i);                while(!que.empty())                {                    int j=que.front();                    que.pop();                    visited[j]=1;                    for(int k=1; k<=N; k++)                        if(!visited[k]&&edge[j][k])                                que.push(k);                }                ans++;            }        }        cout<<ans-1<<endl;    }    return 0;}


0 0