【题目来源】
https://www.luogu.com.cn/problem/U81206
【题目描述】
链式前向星模板题。
读入n个点,m条边,以及flag。若flag==1,则图有向,否则无向。
对每个点输出它的每一条边。
【输入格式】
第一行三个数:n,m,flag,题意如上所示。
第2~1+m行,每行三个数x,y,z。代表从x到y有一条长为z的边。
【输出格式】
若flag=1,则m行。若flag=0,则m*2行。
每行三个数,即该点的编号、所指向点的编号,边的长度。
先按第一个数升序排列,再以链式前向星中的顺序输出即可。 (其实就是i从1到n,再按顺序查找边输出即可)
特殊的,若该点无出边,单独一个空行。
【算法分析】
本题所需链式前向星核心知识点,详见:https://blog.csdn.net/hnjzsyjyj/article/details/126474608
【算法代码】
- /* 链式前向星存图
- val[idx] 表示第 idx 条边的权值。
- e[idx] 表示第 idx 条边的终点。
- ne[idx] 表示与第 idx 条边同起点的最近一次被添加的边的编号。
- h[a] 表示以结点 a 为起点的最近一次被添加的边的编号。这个表述是在使用 ne[idx]=h[a] 时,也即使用 h[a]=idx++ 更新 h[a] 之前而言的。要特别注意这个语境。
- */
-
- #include
- using namespace std;
-
- const int maxn=2000005;
- const int maxm=4000005;
- int e[maxm<<1],ne[maxm<<1],h[maxn],val[maxm<<1],idx;
- // Undirected edges are special directed edges, open double
- // int e[maxm<<1],ne[maxm<<1],h[maxn],val[maxm<<1],idx;
-
- void add(int a,int b,int w) {
- val[idx]=w,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
- }
-
- int main() {
- int n,m,f;
- cin>>n>>m>>f;
- memset(h,-1,sizeof(h));
-
- while(m--) {
- int a,b,c;
- scanf("%d%d%d",&a,&b,&c);
- add(a,b,c);
- if(f==0) add(b,a,c);
- }
-
- for(int i=1; i<=n; i++) {
- for(int j=h[i]; j!=-1; j=ne[j]) {
- printf("%d %d %d\n",i,e[j],val[j]);
- }
- }
-
- return 0;
- }
-
-
-
- /*
- in1:
- 5 5 0
- 1 2 5
- 1 4 6
- 2 3 7
- 3 5 3
- 3 4 1
- out1:
- 1 4 6
- 1 2 5
- 2 3 7
- 2 1 5
- 3 4 1
- 3 5 3
- 3 2 7
- 4 3 1
- 4 1 6
- 5 3 3
- --------
- in2:
- 4 3 1
- 1 3 6
- 3 4 1
- 2 1 3
- out2:
- 1 3 6
- 2 1 3
- 3 4 1
- */
【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/126475298
https://blog.csdn.net/hnjzsyjyj/article/details/126474608
https://www.luogu.com.cn/blog/szbszb/u81206-ti-xie