对于有向图M,若将其所有的边转化为无向边,则得到其基图M‘,若M’是联通的,则称有向图M是弱联通。
对于有向图M,若图中任意两点u,v(u != v)均满足u到v可达,v到u可达,则称此图为强联通。
根据以上定义显然可知,强联通图一定也满足弱联通。
此题首先我们需要找到其所有的弱联通分量。
对于每一个弱联通分量,设此弱联通分量内点的个数为ans,如果此联通分量无环,则需要的边数为ans-1,若有环则为ans。
太挫了,这种题都不会了,怎么变黄!!!
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#pragma comment(linker, "/STACK:1024000000")
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define INF 0x3f3f3f3f
#define Mod 6000007
//** I/O Accelerator Interface .. **/
#define g (c=getchar())
#define d isdigit(g)
#define p x=x*10+c-'0'
#define n x=x*10+'0'-c
#define pp l/=10,p
#define nn l/=10,n
template<class T> inline T& RD(T &x)
{
char c;
while(!d);
x=c-'0';
while(d)p;
return x;
}
template<class T> inline T& RDD(T &x)
{
char c;
while(g,c!='-'&&!isdigit(c));
if (c=='-')
{
x='0'-g;
while(d)n;
}
else
{
x=c-'0';
while(d)p;
}
return x;
}
inline double& RF(double &x) //scanf("%lf", &x);
{
char c;
while(g,c!='-'&&c!='.'&&!isdigit(c));
if(c=='-')if(g=='.')
{
x=0;
double l=1;
while(d)nn;
x*=l;
}
else
{
x='0'-c;
while(d)n;
if(c=='.')
{
double l=1;
while(d)nn;
x*=l;
}
}
else if(c=='.')
{
x=0;
double l=1;
while(d)pp;
x*=l;
}
else
{
x=c-'0';
while(d)p;
if(c=='.')
{
double l=1;
while(d)pp;
x*=l;
}
}
return x;
}
#undef nn
#undef pp
#undef n
#undef p
#undef d
#undef g
using namespace std;
vector<int> vec[100010];
vector<int> wvec[100010];
int deg[100010];
bool mark[100010];
bool cir;
int ans;
struct Q
{
int v,d;
bool operator < (const Q &a)const{
return a.d < d;
}
};
priority_queue<Q> q;
void FindCir()
{
Q f;
int i;
while(q.empty() == false)
{
f = q.top();
q.pop();
if(deg[f.v] < f.d)
continue;
if(f.d)
{
cir = true;
return ;
}
for(i = wvec[f.v].size()-1;i >= 0; --i)
{
--deg[wvec[f.v][i]];
q.push((Q){wvec[f.v][i],deg[wvec[f.v][i]]});
}
}
}
void FindAns(int site,int pre = -1)
{
if(mark[site])
return ;
mark[site] = true;
ans++;
q.push((Q){site,deg[site]});
for(int i = vec[site].size()-1;i >= 0; --i)
{
if(vec[site][i] != pre)
FindAns(vec[site][i],site);
}
}
int main()
{
int u,v,i,n,m,sum;
scanf("%d %d",&n,&m);
memset(deg,0,sizeof(deg));
for(i = 1;i <= m; ++i)
{
scanf("%d %d",&u,&v);
wvec[u].push_back(v);
deg[v]++;
vec[u].push_back(v);
vec[v].push_back(u);
}
memset(mark,false,sizeof(mark));
sum = 0;
for(i = 1;i <= n; ++i)
{
if(mark[i] == false)
{
ans = 0;
while(q.empty() == false)
q.pop();
FindAns(i);
cir = false;
FindCir();
sum += cir ? ans : ans-1;
}
}
printf("%d\n",sum);
return 0;
}