#include <iostream>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
bool vis[1000];
template <class TypeOfVer, class TypeOfEdge>
class adjmatrix_graph{
private:
int Vers;
int Edges;
TypeOfEdge **edge;
TypeOfVer *ver;
TypeOfEdge noEdge;
string GraphKind;
bool DFS(int u, int &num, int visited[]);
bool CheckRoute(int u, int v, int visited[]);
public:
adjmatrix_graph( const string &kd, int vSize, const TypeOfVer d[], const TypeOfEdge noEdgeFlag);
adjmatrix_graph( const string &kd, int vSize, int eSize, const TypeOfVer d[], int **e);
adjmatrix_graph( const string &kd, int vSize, int eSize, const TypeOfEdge noEdgeFlag, const TypeOfVer d[], int **e, const TypeOfEdge w[]);
bool GraphisEmpty() {
return Vers == 0; }
string GetGraphKind(){
return GraphKind; }
bool GetVer(int u, TypeOfVer &data);
int GetFirstAdjVex(int u, int &v);
int GetNextAdjVex(int u, int v, int &w);
bool PutVer(int u, TypeOfVer data);
bool InsertVer(const TypeOfVer &data);
bool Printvers();
int LocateVer(TypeOfVer data);
bool PrintMatrix();
bool CheckRoute(int u, int v);
int Get_InDegree(int u);
int Get_Degree(int u);
bool ExistEdge(int u, int v);
bool TopSort();
bool U_Judge_Cir();
int GetVerNum(){
return Vers;}
int GetEdgeNum(){
return Edges;}
bool Insert_Edge(int u, int v);
bool Insert_Edge(int u, int v, TypeOfEdge w);
bool DeleteVer(const TypeOfVer &data);
bool Delete_Edge(int u, int v);
bool Delete_Edge(int u, int v, TypeOfEdge w);
void DFS_Traverse(int u);
void BFS_Traverse(int u);
~adjmatrix_graph();
};
template<class TypeOfVer,class TypeOfEdge>
adjmatrix_graph<TypeOfVer,TypeOfEdge>::adjmatrix_graph(const string &kd, int vSize, const TypeOfVer d[], const TypeOfEdge noEdgeFlag){
GraphKind = kd;
Vers = vSize;
noEdge = noEdgeFlag;
Edges = 0;
ver = new TypeOfVer[vSize];
edge = new TypeOfVer* [vSize];
for(int i=0;i<vSize;i++) ver[i] = d[i];
for(int i=0;i<vSize;i++){
edge[i] = new TypeOfVer[vSize];
for(int j=0;j<vSize;j++){
edge[i][j]=noEdge;
}
}
}
template<class TypeOfVer,class TypeOfEdge>
adjmatrix_graph<TypeOfVer,TypeOfEdge>::adjmatrix_graph( const string &kd, int vSize, int eSize, const TypeOfVer d[], int **e){
GraphKind = kd;
Vers = vSize;
Edges = eSize;
noEdge = 0;
ver = new TypeOfVer[vSize];
edge = new TypeOfEdge* [eSize];
for(int i=0;i<vSize;i++) ver[i] = d[i];
for(int i=0;i<vSize;i++){
edge[i] = new TypeOfEdge[vSize];
}
for(int i=0;i<vSize;i++){
for(int j=0;j<vSize;j++){
edge[i][j] = e[i][j];
}
}
}
template<class TypeOfVer,class TypeOfEdge>
adjmatrix_graph<TypeOfVer,TypeOfEdge>::adjmatrix_graph( const string &kd, int vSize, int eSize, const TypeOfEdge noEdgeFlag, const TypeOfVer d[], int **e, const TypeOfEdge w[]){
GraphKind = kd;
Vers = vSize;
Edges = eSize;
noEdge = noEdgeFlag;
ver = new TypeOfVer[vSize];
edge = new TypeOfEdge* [eSize];
for(int i=0;i<vSize;i++) ver[i] = d[i];
for(int i=0;i<vSize;i++){
edge[i] = new TypeOfEdge[vSize];
for(int j=0;j<vSize;j++){
edge[i][j] = noEdge;
}
}for(int i=0;i<eSize;i++){
edge[e[i][0]][e[i][1]] = w[i];
if(GraphKind == "UDN") edge[e[i][1]][e[i][0]] = w[i];
}
}
template<class TypeOfVer,class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer,TypeOfEdge>::InsertVer(const TypeOfVer &data){
TypeOfVer *new_ver = new TypeOfVer[Vers+1];
memcpy(new_ver, ver, Vers);
new_ver[Vers] = data;
delete [] ver;
ver = new_ver;
TypeOfEdge **new_edge = new TypeOfEdge *[Vers+1];
for(int i=0;i<=Vers;i++){
new_edge[i] = new TypeOfEdge[Vers+1];
}for(int i=0;i<=Vers;i++){
for(int j=0;j<=Vers;j++){
if(i == Vers||j == Vers) new_edge[i][j] = 0;
else new_edge[i][j] = edge[i][j];
}
}
for(int i=0;i<Vers;i++) delete []edge[i];
delete [] edge;
edge = new_edge;
Vers++;
return true;
}
template<class TypeOfVer,class TypeOfEdge>
int adjmatrix_graph<TypeOfVer,TypeOfEdge>::GetFirstAdjVex(int u, int &v){
if(u<0||u>Vers-1) return -1;
for(int i=0;i<Vers;i++){
if(edge[u][i]!=noEdge){
v = i;
return i;
}
}
return -1;
}
template<class TypeOfVer,class TypeOfEdge>
int adjmatrix_graph<TypeOfVer,TypeOfEdge>::GetNextAdjVex(int u,int v,int &w){
if(u<0||v<0||u>Vers-1||v>Vers-1) return -1;
if(edge[u][v] == 0) return -1;
for(int i=0;i<Vers;i++){
if(edge[u][i]!=noEdge&&i>v){
w = i;
return i;
}
}
return -1;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer,TypeOfEdge>::DeleteVer(const TypeOfVer &data){
int i=LocateVer(data);
if(i==-1) return false;
for(int j=0;j<Vers;j++){
if(edge[j]) Edges--;
}
for(int j=i+1;j<Vers;j++){
ver[j-1] = ver[j];
for(int k=0;k<Vers;k++){
edge[j-1][k] = edge[j][k];
}
for(int k=0;k<Vers;k++){
edge[k][j-1] = edge[k][j];
}
}
Vers--;
return true;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer,TypeOfEdge>::Delete_Edge(int u, int v){
if(u<0||v<0||u>=Vers||v>=Vers) return false;
if(GraphKind == "DG"){
if(edge[u][v] == 0) return false;
edge[u][v] = 0;
Edges--;
}else if(GraphKind == "UDG"){
if(edge[u][v] == 0&&edge[v][u] == 0) return false;
if(edge[u][v]!=0&&edge[v][u]!=0) Edges++;
if(edge[u][v] != 0){
edge[u][v] = 0;
Edges--;
}
if(edge[v][u] != 0){
edge[v][u] = 0;
Edges--;
}
}
return true;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer,TypeOfEdge>::Delete_Edge(int u, int v,TypeOfEdge w){
if(u<0||v<0||u>=Vers||v>=Vers) return false;
if(GraphKind == "UDN"){
if(edge[u][v] == noEdge&&edge[v][u] == noEdge) return false;
if(edge[u][v] != noEdge&&edge[v][u] != noEdge) Edges++;
if(edge[u][v] != noEdge){
edge[u][v] = noEdge;
Edges--;
}
if(edge[v][u] != noEdge){
edge[v][u] = noEdge;
Edges--;
}
}else if(GraphKind == "DN"){
if(edge[u][v] == noEdge) return false;
edge[u][v] = noEdge;
Edges--;
}
return true;
}
template<class TypeOfVer,class TypeOfEdge>
int adjmatrix_graph<TypeOfVer,TypeOfEdge>::LocateVer(TypeOfVer data){
for(int i=0;i<Vers;i++){
if(data == ver[i]) return i;
}
return -1;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer,TypeOfEdge>::Printvers(){
for(int i=0;i<Vers;i++){
if(i) cout<<' ';
cout<<ver[i];
}cout<<endl;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer,TypeOfEdge>::PrintMatrix(){
for(int i=0;i<Vers;i++){
for(int j=0;j<Vers;j++){
cout<<edge[i][j]<<' ';
}cout<<endl;
}
return true;
}
template<class TypeOfVer,class TypeOfEdge>
adjmatrix_graph<TypeOfVer,TypeOfEdge>::~adjmatrix_graph(){
delete [] ver;
for(int i=0;i<Vers;i++) delete[] edge[i];
delete [] edge;
}
int f=0;
template<class TypeOfVer,class TypeOfEdge>
void adjmatrix_graph<TypeOfVer,TypeOfEdge>::DFS_Traverse(int u){
if(!vis[u]){
if(f) cout<<"->";f=1;
cout<<ver[u];
vis[u] = 1;
for(int i=0;i<Vers;i++){
if(edge[u][i]!=0&&!vis[i]){
DFS_Traverse(i);
}
}
}
}
template<class TypeOfVer,class TypeOfEdge>
void adjmatrix_graph<TypeOfVer,TypeOfEdge>::BFS_Traverse(int u){
queue<int> q;
q.push(u);
vis[u]=1;
while(!q.empty()){
int x = q.front();
for(int i=0;i<Vers;i++){
if(!vis[i]&&edge[x][i]!=0){
q.push(i);
vis[i]=1;
}
}q.pop();
if(f) cout<<"->";f=1;
cout<<ver[x];
}
}
template<class TypeOfVer,class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer,TypeOfEdge>::CheckRoute(int u, int v){
int* vis = new int[Vers];
for(int i=0;i<Vers;i++) vis[i] = 0;
CheckRoute(u,v,vis);
}
template<class TypeOfVer,class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer,TypeOfEdge>::CheckRoute(int u, int v,int vis[]){
queue<int> q;
q.push(u);
vis[u] = 1;
while(!q.empty()){
int x = q.front();
if(x == v) return true;
for(int i=0;i<Vers;i++){
if(!vis[i]&&edge[x][i]!=0){
q.push(i);
vis[i]=1;
}
}q.pop();
}
return false;
}
template<class TypeOfVer,class TypeOfEdge>
int adjmatrix_graph<TypeOfVer,TypeOfEdge>::Get_InDegree(int u){
if(GraphKind == "UDG"||GraphKind == "UDN") return -1;
if(u<0||u>=Vers) return -1;
int ans=0;
for(int i=0;i<Vers;i++){
if(i!=u&&edge[i][u]!=noEdge){
ans++;
}
}
return ans;
}
template<class TypeOfVer,class TypeOfEdge>
int adjmatrix_graph<TypeOfVer,TypeOfEdge>::Get_Degree(int u){
if(u<0||u>=Vers) return -1;
int ans=0;
for(int i=0;i<Vers;i++){
if(edge[u][i]!=noEdge) ans++;
}
return ans;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer,TypeOfEdge>::ExistEdge(int u, int v){
if(u<0||v<0||u>=Vers||v>=Vers) return false;
if(edge[u][v]||edge[v][u]) return true;
return false;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer,TypeOfEdge>::Insert_Edge(int u, int v){
if(u<0||v<0||u>=Vers||v>=Vers) return false;
if(GraphKind == "UDG"){
if(edge[u][v]||edge[v][u]) return false;
edge[u][v] = edge[v][u] = 1;
Edges++;
}else if(GraphKind == "DG"){
if(edge[u][v]) return false;
edge[u][v] = 1;
Edges++;
}
return true;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjmatrix_graph<TypeOfVer,TypeOfEdge>::Insert_Edge(int u, int v,TypeOfEdge w){
if(u<0||v<0||u>=Vers||v>=Vers) return false;
if(GraphKind == "UDN"){
if(edge[u][v] != noEdge&&edge[v][u] != noEdge) return false;
edge[u][v] = edge[v][u] = w;
Edges++;
}else if(GraphKind == "DN"){
if(edge[u][v]!=noEdge) return false;
edge[u][v] = w;
Edges++;
}
return true;
}