对于有向图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; }
Codeforce 505D - Mr. Kitayuta's Technology 弱联通分量+拓扑排序
时间: 2024-11-08 23:51:12