【题目来源】
https://www.luogu.com.cn/problem/B3643
【题目描述】
给定一个 n 个顶点 m 条边的无向图。请以邻接矩阵和邻接表的形式输出这一张图。
【输入格式】
第一行输入两个正整数 n 和 m,表示图的顶点数和边数。
第二行开始,往后 m 行,每行输入两个以空格隔开的正整数 u,v,表示 u,v 顶点之间有一条边直接相连。
【输出格式】
首先输出 n 行 n 列的矩阵,以空格隔开每一行之间的数表示邻接矩阵。第 i 行第 j 列的数为 1 则表示顶点 i,j 之间有一条边直接相连;若为 0 则表示没有直接相连的边。
再往后输出 n 行。第 i 行首先先输出一个整数 di,表示这个顶点的度数,再按照从小到大的顺序,依次输出与顶点 i 直接相连的所有顶点。
【数据范围】
数据保证,对于所有数据,1≤n≤1000,1≤m≤100000,且图无重边无自环。
【输入样例】
5 5
1 2
2 3
3 5
1 3
3 4
【输出样例】
0 1 1 0 0
1 0 1 0 0
1 1 0 1 1
0 0 1 0 0
0 0 1 0 0
2 2 3
2 1 3
4 1 2 4 5
1 3
1 3
【算法分析】
● 图的邻接矩阵是唯一的,但邻接表的形式不唯一。
● 图会因输入顺序不同,生成不同的邻接表。通过排序操作 sort(v[i].begin(), v[i].end()),既保证了邻接表输出结果的一致性,也为后续算法提供了统一的数据基础。
【算法代码】
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
int mp[maxn][maxn]; //Adjacency Matrix
vector<int> v[maxn]; //Adjacency List
int n,m; //Vertex count, Edge count
int s,t; //Start point, End point
int main() {
cin>>n>>m;
while(m--) {
cin>>s>>t;
mp[s][t]=1,mp[t][s]=1;
v[s].push_back(t),v[t].push_back(s);
}
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
cout<<mp[i][j]<<" ";
}
cout<<endl;
}
for(int i=1; i<=n; i++) {
cout<<v[i].size()<<" ";
sort(v[i].begin(),v[i].end());
for(int j=0; j<v[i].size(); j++) {
cout<<v[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
/*
input:
5 5
1 2
2 3
3 5
1 3
3 4
output:
0 1 1 0 0
1 0 1 0 0
1 1 0 1 1
0 0 1 0 0
0 0 1 0 0
2 2 3
2 1 3
4 1 2 4 5
1 3
1 3
*/
【参考文献】
https://blog.youkuaiyun.com/hnjzsyjyj/article/details/116245897
https://blog.youkuaiyun.com/hnjzsyjyj/article/details/101233779