大致题意给你有一个点数为n<=100的有向图。
求解两个子任务:
1:最少给多少个点信息,这些点的信息可以顺着有向边传遍全图。
2:最少要加多少条边,使得整个图强联通。
求强联通分量再缩点后得到一个有向无环图。
设其入度为0的点数为t1,出度为0的点数为t2
1的答案即为强联通缩点之后入度为0的点的数量t1。
2的答案即为max(t1,t2).
注意一个特殊情况:若缩点后只有一个点了(即原图便是强联通的)此时t1=1,t2=1但是第二个任务的答案应当是0。
AC代码:
#include#include #include #include #define rep(i,a,b) for(int i=a;i<=b;++i)using namespace std;const int MAXN=110;int n,cnt;int graph[MAXN][MAXN];int DFN[MAXN],low[MAXN],Stap[MAXN],label[MAXN];bool instake[MAXN];int Stop,Bcnt;int adjm[MAXN][MAXN];int in[MAXN],out[MAXN];void init(){ memset(graph,0,sizeof(graph)); memset(DFN,0,sizeof(DFN)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); memset(adjm,0,sizeof(adjm)); memset(instake,0,sizeof(instake)); int t; cnt=0;Stop=0;Bcnt=0; rep(i,1,n) { while(scanf("%d",&t)==1&&t) { graph[i][++graph[i][0]]=t; } }}void tarjan(int u){ DFN[u]=low[u]=++cnt; instake[u]=1; Stap[++Stop]=u; rep(i,1,graph[u][0]) { int v=graph[u][i]; if(!DFN[v]) { tarjan(v); if(low[v]