| C电压 | ||
|
第一行两个空格分隔的正整数N和M,表示电路中有N个节点和M根电阻。
接下来M行,第i行有两个空格分隔的正整数Ai和Bi(1<=Ai<=N,1<=Bi<=N,Ai≠Bi),表示第i个电阻连接节点Ai和节点Bi。
输出一行一个整数,代表电路维护时可选择的使其不流的电阻个数。
4 4
1 2
2 3
3 2
4 3
2
这道题与二分图有关,我们要使得去掉一条边后使得电路图成为一个标准的二分图
所以我们用dfs搜一遍,然后找到一条被所有的奇数边包括并且不被所有的偶数边包括的边 并且找出这样的边的个数即可
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
int n,m,x,y,ans,f,i,cnt=1;
int he[100010],de[100010],color[(100010)<<2],to[(100010)<<2],ne[(100010)<<2],a[100010],aa[100010];
void add(int x,int y)
{
cnt++;
to[cnt]=y;
ne[cnt]=he[x];
he[x]=cnt;
}//建树
void dfs(int x)
{
for(int i=he[x];i;i=ne[i])
{
if(de[to[i]]==-1)de[to[i]]=de[x]+1,color[i]=color[i^1]=1,dfs(to[i]);
}
}
void find(int x)
{
for(int i=he[x];i;i=ne[i])
{
if(color[i]&&de[to[i]]>de[x])find(to[i]),a[x]+=a[to[i]],aa[x]+=aa[to[i]];
}
if(de[x]&&a[x]==f&&!aa[x])ans++;//满足两个条件
}
int main()
{
scanf("%d%d",&n,&m);
//cin>>n>>m;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);//无向图
}
memset(de,-1,sizeof(de));
for(int i=1;i<=n;i++)if(de[i]==-1)de[i]=0,dfs(i);//搜索
for(int j=1;j<=n;j++)
{
for(i=he[j];i;i=ne[i])
{
if(!color[i]&&de[to[i]]<de[j]){
if((de[j]-de[to[i]])&1)aa[j]++,aa[to[i]]--;
else f++,a[j]++,a[to[i]]--;
}
}
}
if(f==1)ans++;
for(int i=1;i<=n;i++)if(!de[i])find(i);
//cout<<ans;
printf("%d",ans);
}
原文:https://www.cnblogs.com/cocacolalala/p/11377489.html