AtCoder Grand Contest 011 C - Squared Graph

Keywords: REST

meaning of the title

An undirected graph G with n vertices and m edges. Now we construct a new graph G', with n*n points, each of which is a pair of numbers (x,y). There is an edge from (a,b) to (c,d) in the new graph if and only if there are edges from a to C and from B to D in the original graph. Ask the number of connected blocks in the new graph.
n<=100000,m<=200000

Analysis

Firstly, we find that if (a,b) has path arrival (c,d), there must be a path from a to C and a path from B to D in the original graph, and the length of the two paths is the same (not necessarily a simple path).
If the path exists, then a and c must be in a connected block, and b and d must be in a connected block.
Now consider the contributions between two connected blocks, that is, those that satisfy the first dimension at the first connected block and the second dimension at the second connected block.
It's not difficult to find out by hand that if two connected blocks are bipartite graphs, we can get two connected blocks.
If one of them is not a bipartite graph, there is only one connected block.
Take a special look at the individual points.
The rest is simple.

Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long LL;

const int N=100005;

int n,m,cnt,last[N],dep[N],s;
bool vis[N],flag;
struct edge{int to,next;}e[N*4];

int read()
{
    int x=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

void addedge(int u,int v)
{
    e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;
    e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;
}

void dfs(int x,int fa)
{
    vis[x]=1;s++;
    for (int i=last[x];i;i=e[i].next)
        if (vis[e[i].to]&&e[i].to!=fa) flag|=dep[x]==dep[e[i].to];
        else if(!vis[e[i].to]) dep[e[i].to]=dep[x]^1,dfs(e[i].to,x);
}

int main()
{
    n=read();m=read();
    for (int i=1;i<=m;i++)
    {
        int x=read(),y=read();
        addedge(x,y);
    }
    LL ans=0;int t1=0,t2=0,t3=0;
    for (int i=1;i<=n;i++)
    {
        if (vis[i]) continue;
        flag=0;s=0;
        dfs(i,0);
        if (s==1) ans+=n*2-1,t3++;
        else if (!flag) ans+=2,t1++;
        else ans++,t2++;
    }
    ans-=(LL)t3*(t3-1);
    ans+=(LL)t1*(t1-1)*2+(LL)t2*(t2-1)+(LL)t1*t2*2;
    printf("%lld",ans);
    return 0;
}

Posted by RunningUtes on Sun, 10 Feb 2019 05:06:19 -0800