AGC011 C Squared Graph
阿新 • • 發佈:2018-12-12
題意
定義兩個圖的乘法是:點數為它們的乘積,新圖中(x,y)到(z,w)有邊,當且僅當第一個圖(x,z)有邊,第二個圖(y,w)有邊 給出一個無向圖G,求它的平方的連通分量個數
題解
我們考慮相對一般點的情形:圖A乘上圖B 首先考慮那些孤點(即度數為0),設AB孤點個數為I 由於孤點不和任何點有連線,所以在新圖中,它所對應的那一行(列)就肯定是獨立的 也就是說,跟孤點有關的就是 在原圖中的一個二分圖,我們只能黑->白->黑地走,所以在對應的乘積上會有兩個連通塊 而非二分圖則可以保證最後形成的是一個連通塊 而二分圖乘上非二分圖,也是一個連通塊 綜上,答案就是 (P為非二分圖數量,Q為二分圖數量)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1000000+5;
typedef long long ll;
struct node{
int u,v,nxt;
}edge[N*2];
int head[N],mcnt;
int du[N];
void add_edge(int u,int v){
mcnt++;
edge[mcnt].u=u;
edge[mcnt].v=v;
edge[mcnt].nxt=head[u];
head[u]=mcnt;
du[u]++;
}
ll I,P,Q;
bool tag[N];
bool vis[N];
bool flag;
void dfs (int u){
vis[u]=1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].v;
if(!vis[v]){
tag[v]=tag[u]^1;
dfs(v);
}
else
if(tag[u]==tag[v])
flag=false;
}
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
for(int i=1;i<=n;i++){
if(vis[i])
continue;
if(du[i]==0){
I++;
continue;
}
flag=true;
dfs(i);
if(flag)
Q++;
else
P++;
}
ll ans=1ll*2*I*n-1ll*I*I+1ll*P*P+2ll*P*Q+2ll*Q*Q;
printf("%lld\n",ans);
}