图论小结

来源:互联网 发布:dcp打包软件 编辑:程序博客网 时间:2024/06/15 13:30

BellmanFord\dijkstra\堆优化\FloydWarshall\prime\kruskal算法的简单实现

//图的表示const int maxv = 1e5;//struct Edge{ int to, cost; };//vector<Edge> G[maxv];vector<int> G[maxv];int main(){    int v, e;    scanf("%d%d", &v, &e);    //Edge temp;    for(int i = 0; i < e; i++){        int s, t;        scanf("%d%d", &s, &t);        G[s].push_back(t);        G[t].push_back(s);    }    return 0;}//图的遍历、 二分图染色判定问题const int maxv = 1e5;vector<int> G[maxv];int color[maxv];int V;//顶点染成1或-1 bool dfs(int v, int c){    color[v] = c;//顶点c染成颜色c     for(int i = 0; i < G[v].size(); i++){        if(color[G[v][i]] == c) return false;//相邻顶点同色        //如果相邻顶点还没被染色,则染成-c         if(color[G[v][i]] == 0 && !dfs(G[v][i], -c)) return false;    }    //如果所有顶点都染过色了,则返回true;     return true;}void slove(){    for(int i = 0; i < V; i++){        if(color[i] == 0){//如果顶点没有被染色,染1;             if(!dfs(i, 1)){                printf("No\n");                 return;            }        }    }    printf("Yes\n");}//单源最短路:BellmanFord算法const int inf = 1e9;const int maxv = 1e5;struct edge{ int from, to, cost; };edge es[maxv];int d[maxv];int pre[maxv];int V, E;//单源最短路:BellmanFord算法void BellmanFord(int s){    for(int i = 0; i < V; i++) d[i] = inf;    d[s] = 0;    pre[s] = -1;    while(true){        bool update = false;        for(int i = 0; i < E; i++){            edge e = es[i];            if(d[e.from] != inf && d[e.to] > d[e.from] + e.cost){                d[e.to] = d[e.from] + e.cost;                pre[e.to] = e.from;                update = true;            }        }        if(!update) break;    }}//路径还原 void getPath(int v){    if(pre[v] == -1){        printf("%d ", v);        return;     }     getPath(pre[v]);    printf("%d ", v);}//检查是否存在负圈bool findNegativeLoop(){    memset(d, 0, sizeof(d));    for(int i = 0; i < V; i++){        for(int j = 0; j < E; j++){            edge e = es[j];            if(d[e.to] > d[e.from] + e.cost){                d[e.to] = d[e.from] + e.cost;                //如果第n次仍更新了,则存在负圈                 if(i == V - 1) return false;            }        }    }    return true;} int main(){    scanf("%d%d", &V, &E);    E *= 2;    for(int i = 0; i < E; i+= 2){        scanf("%d%d%d", &es[i].from, &es[i].to, &es[i].cost);        es[i+1].from = es[i].to; es[i+1].to = es[i].from;        es[i+1].cost = es[i].cost;     }    BellmanFord(0);    cout << d[6] << endl;    getPath(6);cout << endl;    string str = findNegativeLoop() ? "No negative loop" : "Exist negative loop";    cout << str << endl;     return 0;}/*input:7 10 0 1 20 2 51 2 41 3 61 4 102 3 23 5 14 5 34 6 55 6 9output:160 2 3 5 4 6No negative loop*/const int inf = 1e8;const int maxv = 1e3;int cost[maxv][maxv];//初始化inf int d[maxv];bool used[maxv];int pre[maxv];int V, E;//单源最短路:Dijkstra算法 O(V^2)void Dijkstra(int s){    for(int i = 0; i < V; i++){        d[i] = inf;         used[i] = false;    }    d[s] = 0;    pre[s] = -1;    while(true){        int v = -1;        for(int i = 0; i < V; i++){            if(!used[i] && (v == -1 || d[i] < d[v])){                v = i;            }        }        if(v == -1) break;        used[v] = true;        for(int i = 0; i < V; i++){            if(d[i] > d[v] + cost[v][i]){                d[i] = d[v] + cost[v][i];                pre[i] = v;            }        }    }}//路径还原 void getPath(int v){    if(pre[v] == -1){        printf("%d ", v);        return;     }     getPath(pre[v]);    printf("%d ", v);}int main(){    scanf("%d%d", &V, &E);    int u, v, val;    for(int i = 0; i < V; i++){        for(int j = 0; j < V; j++){            cost[i][j] = inf;         }    }    for(int i = 0; i < E; i++){        scanf("%d%d%d", &u, &v, &val);        cost[u][v] = cost[v][u] = val;    }    Dijkstra(0);    cout << d[6] << endl;    getPath(6);cout << endl;    return 0;}/*input:7 10 0 1 20 2 51 2 41 3 61 4 102 3 23 5 14 5 34 6 55 6 9output:160 2 3 5 4 6*///单源最短路:Dijkstra算法 堆优化O(E*logV)const int inf = 1e8;const int maxv = 1e3;struct edge{int to, cost;}; struct Node{    int dis, v;//最短距离及对应的顶点    friend bool operator < (Node n1, Node n2){        return n1.dis > n2.dis;    } };vector<edge> G[maxv];int pre[maxv];int d[maxv];int V, E;//单源最短路:Dijkstra算法 堆优化O(E*logV)void Dijkstra(int s){    fill(d, d + V, inf);    d[s] = 0;    pre[s] = -1;    priority_queue<Node> que;    Node temp; temp.dis = 0; temp.v = s;    que.push(temp);    while(!que.empty()){        Node node = que.top(); que.pop();        int v = node.v;        if(d[v] < node.dis) continue;        for(int i = 0; i < G[v].size(); i++){            edge e = G[v][i];            if(d[e.to] > d[v] + e.cost){                d[e.to] = d[v] + e.cost;                temp.dis = d[e.to]; temp.v = e.to;                que.push(temp);                pre[e.to] = v;            }        }    }}//路径还原 void getPath(int v){    if(pre[v] == -1){        printf("%d ", v);        return;     }     getPath(pre[v]);    printf("%d ", v);}int main(){    scanf("%d%d", &V, &E);    int u, v, val;    edge temp;    for(int i = 0; i < E; i++){        scanf("%d%d%d", &u, &v, &val);        temp.cost = val;        temp.to = v; G[u].push_back(temp);        temp.to = u; G[v].push_back(temp);    }    Dijkstra(0);    cout << d[6] << endl;    getPath(6);cout << endl;    return 0;}/*input:7 10 0 1 20 2 51 2 41 3 61 4 102 3 23 5 14 5 34 6 55 6 9output:160 2 3 5 4 6*/const int inf = 1e8;const int maxv = 1e3;int d[maxv][maxv];int V, E;//任意两点间最短距离 Floyd-Warshall算法 O(V^3) void FloydWarshall(){    for(int k = 0; k < V; k++){        for(int i = 0; i < V; i++){            for(int j = 0; j < V; j++)                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);        }    }}int main(){    scanf("%d%d", &V, &E);    for(int i = 0; i < V; i++){        for(int j = 0; j < V; j++){            if(i == j){                d[i][j] = 0;            }else                d[i][j] = inf;        }    }    int u, v, val;    for(int i = 0; i < E; i++){        scanf("%d%d%d", &u, &v, &val);        d[u][v] = d[v][u] = val;    }    FloydWarshall();    cout << d[0][6] << endl;        return 0;}/*input:7 10 0 1 20 2 51 2 41 3 61 4 102 3 23 5 14 5 34 6 55 6 9output:16*///最小生成树、prime算法,同dijkstra算法类似const int inf = 1e8;const int maxv = 1e3;int cost[maxv][maxv];int mincost[maxv];  //从集合x出发的到每个顶点的最小权值bool used[maxv];    //顶点是否包含在集合x中(集合x为MST的子集) int V, E; //最小生成树: prime算法int Prime(){    for(int i = 0; i < V; i++){        mincost[i] = inf;        used[i] = false;    }    mincost[0] = 0;    int res = 0;    while(true){        int v = -1;        for(int i = 0; i < V; i++){            if(!used[i] && (v == -1 || mincost[i] < mincost[v])){                v = i;            }        }           if(v == -1) break;        used[v] = true;        res += mincost[v];        for(int i = 0; i < V; i++){            mincost[i] = min(mincost[i], cost[v][i]);        }    }    return res;} int main(){    scanf("%d%d", &V, &E);    for(int i = 0; i < V; i++){        for(int j = 0; j < V; j++){            cost[i][j] = inf;        }    }    int u, v, val;    for(int i = 0; i < E; i++){        scanf("%d%d%d", &u, &v, &val);        cost[u][v] = cost[v][u] = val;    }    cout << "MST: " << Prime() << endl;     return 0;}/*input:7 10 0 1 20 2 51 2 41 3 61 4 102 3 23 5 14 5 34 6 55 6 9output:MST: 17*///最小生成树: kruskal算法#include<stdio.h>#include<iostream>#include<string.h>#include<math.h>#include<algorithm>#include<queue>#include<set>#include<iterator>#include<map>#include<stack>using namespace std;const int inf = 1e8;const int maxv = 1e3;struct edge{int u, v, cost; };bool cmp(edge e1, edge e2){    return e1.cost < e2.cost;}edge es[maxv];int root[maxv];int rank[maxv];int V, E; void init(int v){    for(int i = 0; i < V; i++){        root[i] = i;        rank[i] = 0;    }} int find(int x){    if(root[x] == x) return x;    return root[x] = find(root[x]);}bool same(int x, int y){    return find(x) == find(y);}void unit(int x, int y){    x = find(x);     y = find(y);    if(x == y) return;    if(rank[x] < rank[y]){        root[x] = y;    }else{        root[y] = x;        if(rank[x] == rank[y]) rank[x]++;    }}//最小生成树: kruskal算法int Kruskal(){    sort(es, es + E, cmp);    init(V);//并查集初始化     int res = 0;    for(int i = 0; i < E; i++){        if(!same(es[i].u, es[i].v)){                unit(es[i].u, es[i].v);            res += es[i].cost;        }           }    return res; }int main(){    scanf("%d%d", &V, &E);    int u, v, val;    for(int i = 0; i < E; i++){        scanf("%d%d%d", &es[i].u, &es[i].v, &es[i].cost);    }    cout << "MST: " << Kruskal() << endl;       return 0;}/*input:7 10 0 1 20 2 51 2 41 3 61 4 102 3 23 5 14 5 34 6 55 6 9output:MST: 17*/
原创粉丝点击