//
// main.cpp
// helpbuptguoan
//
// Created by New_Life on 16/8/24.
// Copyright © 2016年 chenhuan001. All rights reserved.
//
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <map>
#include <random>
#include <algorithm>
using namespace std;
#define N 5 // 图的大小
const int TYPE = 3;/*用于设置图存储的数据结构,
1: 二维数组a[][]
2: 一维数组a[] 存放vector
3: map
*/
const int INF = 1e3; //值上限
struct Graph{
//第一种数据结构:二维数组
int a1[N][N];
//第二种数据结构
vector< pair<unsigned int,unsigned char> >a2[N];
//第三种
map< pair<unsigned int,unsigned int>,unsigned char > a3;
int s;//起点
int length[N];//保存起点s到其他点的最短路
}G;
void init()//初始化,把每个数据结构都清空.
{
G.a3.clear();
for (int i=0; i<N; i++) {
G.a2[i].clear();
for(int j=0;j<N;j++){
G.a1[i][j] = -1;//初始化不能到达,为-1
}
}
}
void add_edge(int u,int v){
int w = rand()%10+1;
if(TYPE == 1){
G.a1[u][v] = w;
}
else if(TYPE == 2){
pair<unsigned int,unsigned char> node;
node.first = v;
node.second = w;
G.a2[u].push_back(node);
}else{
pair<unsigned int,unsigned int> node;
node.first = u;
node.second = v;
G.a3[node] = w;
}
}
void GetRandGraph()
{
int tmpv[N];
for(int i=0;i<N;i++)
{
int cnt=0;
for(int j=0;j<N;j++)
{
if(j==i) continue;
tmpv[cnt++] = j;
}
int tcnt = cnt;
for(int j=0;j<min(tcnt,10);j++)//随机产生10个
{
int v = rand()%cnt;
add_edge(i,tmpv[v]);
for(int k=v;k<cnt-1;k++)//全体左移
{
tmpv[k] = tmpv[k+1];
}
cnt--;
}
}
}
void Dijkstra()
{
bool mark[N];
for(int i=0;i<N;i++)
{
G.length[i] = INF;
mark[i] = 0;
}
G.length[ G.s ] = 0;
for(int t=0; t<N; t++)// N次循环
{
int mi = INF,id = -1;
for(int i=0;i<N;i++)
{
if(mark[i] == 0 && G.length[i]<mi){//找出未标记的距离最小点
mi = G.length[i];
id = i;
}
}
mark[id] = 1;
if(TYPE == 1){
for(int i=0;i<N;i++){
if(G.a1[id][i]!=-1 && mark[i]==0 && mi+G.a1[id][i] < G.length[i])//三角不等式
{
G.length[i] = mi+G.a1[id][i];//更新最小值
}
}
}else if(TYPE == 2){
for(int i=0;i<G.a2[id].size();i++){//遍历邻接表
int v = G.a2[id][i].first;
int w = G.a2[id][i].second;
if(mark[v]==0 && mi+w < G.length[v])
{
G.length[v] = mi+w;
}
}
}else//type == 3
{
for(int i=0;i<N;i++){
if(mark[i] == 0){
int w;
if( (w=G.a3[make_pair(id, i)])!=0 ){
G.length[i] = min(G.length[i],mi + w);
}
}
}
}
}
}
void print()
{
//统一以邻接表形式输出图
//
if(TYPE == 2){
for(int i=0;i<N;i++)
{
for(int j=0;j<G.a2[i].size();j++)
G.a1[i][ G.a2[i][j].first ] = G.a2[i][j].second;
}
}else if(TYPE == 3){
for(int i=0;i<N;i++)
for(int j=0;j<N;j++) if( G.a3[ make_pair(i, j) ]!=0 ) G.a1[i][j] = G.a3[ make_pair(i, j) ];
}
printf("随机图的邻接表形式:\n");
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
printf("%d\t",G.a1[i][j]);
}
printf("\n");
}
printf("////////////////////////\n");
printf("从0到各个节点的最短距离:\n");
printf("节点:");
for(int i=0;i<N;i++) printf("%d ",i);
printf("\n");
printf("距离:");
for(int i=0;i<N;i++){
printf("%d ",G.length[i]);
}
printf("\n");
}
int main(int argc, const char * argv[]) {
init();//初始化
GetRandGraph();
Dijkstra();
print();//打印图信息
return 0;
}