標籤:
對於有向圖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,ntemplate<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 gusing 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 弱聯通分量+拓撲排序