dijkstra

来源:互联网 发布:deepin linux卸载软件 编辑:程序博客网 时间:2024/05/29 13:21

题目的链接如下
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1311
我的想法是先使用dijkstra算法求出最短的路径 求出最短路径后 将整个最短路径中的边按从小到大进行排序 求出最短路径和要达到的值的差值,从大的边开始遍历 计算要改变最多几个边才能达到差值 就算出了结果!

#include <iostream>#include <vector>#include <algorithm>using namespace std;const int MAXN = 102;const int MAXINF = 100000;int graph[MAXN][MAXN];void initGraph( int n)//对邻接矩阵进行初始化{    for (int i = 1; i <= n; i++)    {        for (int j = 1; j <= n; j++)        {            if (i == j)                graph[i][j] = 0;            else                graph[i][j] = MAXINF;        }    }}void dijkstra(int start, int *pre,int *low,int n)//pre存放最短路径的前驱节点 low存放原点到所有点路径长度{    bool *s = new bool[n + 2];//将已经找到最短路径的点放到s集合中    for (int i = 1; i <= n; i++)    {        s[i] = false;        if (i == start)            pre[start] = start;        else            pre[i] = start;    }    s[start] = true;    low[start] = 0;    pre[start] = start;    //int prenode = start;    int minpath = MAXINF;    int nextnode;    for (int j = 1; j <= n; j++)    {        low[j] = graph[start][j];    }    for (int i = 2; i <= n;i++)//确定其他n-1个点的最短路径    {        minpath = MAXINF;        for (int j = 1; j <= n; j++)//寻找没有加入s集合中的 且从start点出发最近的那个点        {            if (!s[j] && minpath > low[j])            {                minpath = low[j];                nextnode = j;            }        }        s[nextnode] = true;//将它加入到s集合中        //pre[nextnode] = prenode;//确定它的前驱节点        //prenode = nextnode;        for (int j = 1; j <= n;j++)//利用这个点 更新start点到其他点的最小距离        {            if (!s[j]&&graph[nextnode][j]!=MAXINF)            {                int newpath = low[nextnode] + graph[nextnode][j];                if (newpath < low[j])                {                    low[j] = newpath;                    pre[j] = nextnode;                }            }        }    }    delete[] s;}void printPath(int *pre,int n){    if (pre[n] != n)        printPath(pre, pre[n]);    cout << n << " ";}int main(){    int n, m, c;//n为点的个数 m为边的个数 c为要想得到的值    int u,v,w;    while (cin >> n >> m >> c, n)    {        initGraph(n);        for (int i = 1; i <= m; i++)//输入图        {            cin >> u >> v >> w;            graph[u][v] = w;        }        int *pre = new int[n + 2];//pre中存放最短路径的前驱节点        int *low = new int[n + 2];//存放从1点到其他点的最短距离        dijkstra(1, pre, low, n);        int currentdistance = low[n];//当前从1点到n点的最短路径值        int difference = currentdistance - c;//要缩小多少值        //printPath(pre, n);        vector<int> path;        int tempnode = n;        while (pre[tempnode] != tempnode)        {            path.push_back(graph[pre[tempnode]][tempnode]);            tempnode = pre[tempnode];        }        sort(path.begin(),path.end());        int count = 0;        int sum = 0;        for (int i = path.size() - 1; i >= 0; i--)        {            sum += path[i];            count++;            if (sum >= difference)                break;        }        cout << count << endl;        path.clear();        delete[] pre;        delete[] low;    }    return 0;}
0 0
原创粉丝点击