试题编号: | 201509-4 |
试题名称: | 高速公路 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: |
问题描述 某国有n个城市,为了使得城市间的交通更便利,该国国王打算在城市之间修一些高速公路,由于经费限制,国王打算第一阶段先在部分城市之间修一些单向的高速公路。 输入格式 输入的第一行包含两个整数n, m,分别表示城市和单向高速公路的数量。 输出格式 输出一行,包含一个整数,表示便利城市对的数量。 样例输入 5 5 样例输出 3 样例说明
评测用例规模与约定 前30%的评测用例满足1 ≤ n ≤ 100, 1 ≤ m ≤ 1000; |
分析:
本题考察的是求有向图中强连通分量的应用,该题采用的是tarjan算法,关于tarjan算法可以阅读tarjan算法-解决有向图中求强连通分量的利器这篇文章。
不多说,上代码:
#include "Stdafx.h" #include <iostream> #include <stack> using namespace std; #define MAX_VERTEX_SIZE 10001 struct EdgeNode{ int vertex; EdgeNode *nextArc; }; struct VerTexNode{ EdgeNode* firstArc; }; struct Graph{ int n,e; VerTexNode vNode[MAX_VERTEX_SIZE]; }; int time = 0; int low[MAX_VERTEX_SIZE]; int dfn[MAX_VERTEX_SIZE]; int visited[MAX_VERTEX_SIZE]; int inStack[MAX_VERTEX_SIZE]; int ans = 0;//存储运算结果 stack<int> st; Graph graph; void initeGraph(int n,int m) { for(int i = 1;i<=n;i++) { graph.vNode[i].firstArc = NULL; } graph.n = n; graph.e = m; } //头插法建立图 void creatGraph(int s,int v) { EdgeNode *edgeNode = new EdgeNode; edgeNode->vertex = v; edgeNode->nextArc = graph.vNode[s].firstArc; graph.vNode[s].firstArc = edgeNode; } int min(int a,int b) { if(a>b) return b; else return a; } void trajan(int u) { dfn[u] = low[u] = time++; st.push(u); visited[u] = 1; inStack[u] = 1; EdgeNode *edgePtr = graph.vNode[u].firstArc; while(edgePtr !=NULL) { int v = edgePtr->vertex; if(visited[v] == 0) { trajan(v); low[u] = min(low[u],low[v]); } /*之前没有对inStack[v]进行判断,又可能当前的v已经出栈了,这个时候就会出错。 所以导致我的最后得分为80分。 加上if条件,最后为满分。 切记!切记!切记!!! */ else if(inStack[v] == 1) { low[u] = min(low[u],dfn[v]); } edgePtr = edgePtr->nextArc; } int result = 0; if(dfn[u] == low[u]) { int vtx; //cout<<"set is: "; do{ result++; vtx = st.top(); st.pop(); inStack[vtx] = 0;//表示已经出栈 /* cout<<vtx<<‘ ‘;*/ }while(vtx !=u ); if(result > 1) { ans += result*(result-1)/2; } result = 0; } } int main() { int n,m; int s,a; cin>>n>>m; initeGraph(n,m); for(int i = 1;i<=n;i++) { visited[i] = 0; inStack[i] = 0; dfn[i] = 0; low[i] = 0; } for(int j = 1;j<=m;j++) { cin>>s>>a; creatGraph(s,a); } for(int i =1;i<=n;i++) if(visited[i] == 0) trajan(i); cout<<ans<<endl; return 0; }
时间: 2024-12-19 07:37:51