P7991 [USACO21DEC] Connecting Two Barns S

好像没有人用 dfs 判连通块,我来水一发

思路、实现

通过 dfs 把连通块当作新图结点并储存。

此时一共有三种情况。

第一种是 $1$ 和 $n$ 之间已经连通,不需要进行操作。

第二种是需要进行连接一次来达到题目要求。

第三种是需要进行连接两次来达到题目要求。

上述三种情况的最小价值即为最终答案,分类讨论即可。

(这是 dfs 部分代码)

bool vis[MAXN];
void dfs(int x)
{
    G2[tot].push_back(x);
    vis[x]=true;
    for(int i=0;i<G[x].size();i++)
    {
        int y=G[x][i];
        if(vis[y])continue;
        dfs(y);
    }
}

Code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=2e5+10;
const ll INF=0x3f3f3f3f3f3f3f3f;

int n,m,tot;//tot 为连通块计数器
ll ans;
vector<int>G[MAXN],G2[MAXN];//G2 为新图

bool vis[MAXN];
void dfs(int x)
{
    G2[tot].push_back(x);
    vis[x]=true;
    for(int i=0;i<G[x].size();i++)
    {
        int y=G[x][i];
        if(vis[y])continue;
        dfs(y);
    }
}

ll calc(int x,int y)
{
    ll cnt=INF;
    if(G2[x].size()>G2[y].size())swap(x,y);
    int l=G2[y].size();
    for(int i=0;i<G2[x].size();i++)
    {
        int u=G2[x][i];
        int pos=lower_bound(G2[y].begin(),G2[y].end(),u)-G2[y].begin();
        int v1=G2[y][min(pos,l-1)],v2=G2[y][max(0,pos-1)];
        cnt=min(cnt,(ll)(v1-u)*(v1-u));
        cnt=min(cnt,(ll)(v2-u)*(v2-u));
    }
    return cnt;
}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        tot=0;
        ans=INF; 
        for(int i=1;i<=n;i++)
        {
            G[i].clear();
            G2[i].clear();
        }
        memset(vis,0,sizeof(vis));//以上为初始化
        for(int i=1;i<=m;i++)
        {
            int u,v;
            cin>>u>>v;
            G[u].push_back(v);
            G[v].push_back(u);
        }
        tot++;
        dfs(1);
        tot++;
        dfs(n);
        for(int i=1;i<=n;i++)
        {
            if(vis[i])continue;
            tot++;
            dfs(i);
        }
        for(int i=1;i<=tot;i++)sort(G2[i].begin(),G2[i].end());//这里用 set 代替 vector 也可实现排序
        ans=min(ans,calc(1,2));
        for(int i=3;i<=tot;i++)ans=min(ans,calc(1,i)+calc(2,i));
        cout<<ans<<'\n';
    }
    return 0;
}

P.s.:没人试试 Tarjan 判连通块吗 qwq

posted @ 2023-07-06 20:58  H2ptimize  阅读(13)  评论(0)    收藏  举报  来源