理想路径(Ideal Path,UVa 1599)

来源:互联网 发布:优惠券系统源码 编辑:程序博客网 时间:2024/04/28 15:41

题意:给一个n个点m条边(2 <= n <= 100000,1 <= m <= 200000)的无向图,每条边上都涂有一种一种颜色。求从结点1到结点n的一条路径,使得经过的变数尽量少,在此前提下,经过边的颜色序列的字典序最小。一对结点间可能有多条边,一条边可能连接两个相同的结点。输入保证节点1可以达到结点n。颜色为1-10^9的整数


分析:两次BFS,第一次从结点n逆向BFS,得到每个节点i到结点n的最短距离step[i],之后再从结点1正向BFS,每次到达一个新节点时保证step的值恰好减少1,如果有多种走法,则选择颜色字典序最小的走;若存在多条相同边,则一同压入队列进行判断,直至到结点n。

PS: 邻接表真的是个好东西啊

参考代码

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<vector>#include<string>#include<map>#include<sstream>#include<queue>#include<cctype>using namespace std;#define MAX 100001vector<int> g[MAX];vector<int> c[MAX*2];int ans[MAX];int step[MAX];int vis[MAX];queue<int> q;void bfs1(int n) {        step[n] = 0;        while(!q.empty()) q.pop();        q.push(n);        while(!q.empty()) {                int u = q.front();                q.pop();                int size = g[u].size();                for(int v=0;v<size;v++) {                        int vv = g[u][v];                        int s = step[u] + 1;                        if(vv == 1) {                                step[1] = s;                                return;                        }                        if(step[vv] == -1) {                                step[vv] = s;                                q.push(vv);                        }                }        }}void bfs2() {        while(!q.empty()) q.pop();        q.push(1);        memset(vis,0,sizeof(vis));        while(!q.empty()) {                int u = q.front();                q.pop();                int mi = -1;                int size = g[u].size();                for(int v=0;v<size;v++) {                        int vv = g[u][v];                        if(step[vv] == step[u] - 1)                        if(mi == -1) mi = c[u][v];                        else mi = min(mi,c[u][v]);                }                if(ans[step[1]-step[u]] == 0) ans[step[1]-step[u]] = mi;                else ans[step[1]-step[u]] = min(mi,ans[step[1]-step[u]]);                for(int v=0;v<size;v++) {                        int vv = g[u][v];                        if(!vis[vv] && step[vv] == step[u] - 1 && c[u][v] == mi) {                                q.push(vv);                                vis[vv] = 1;                        }                }        }}int main() {        int n,m;        while(~scanf("%d%d",&n,&m) && (n || m)) {                for(int i=0;i<MAX;i++) {                        g[i].clear();                        c[i].clear();                }                while(m--) {                        int a,b,c1;                        scanf("%d%d%d",&a,&b,&c1);                        if(a == b) continue;                        g[a].push_back(b);                        g[b].push_back(a);                        c[a].push_back(c1);                        c[b].push_back(c1);                }                memset(ans,0,sizeof(ans));                memset(step,-1,sizeof(step));                bfs1(n);                bfs2();                printf("%d\n",step[1]);                for(int i=0;i<step[1];i++)                        i != step[1] - 1 ? printf("%d ",ans[i]) : printf("%d\n",ans[i]);        }        return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孩子做事情拖拉不专注怎么办 新热水壶有味道怎么办 新买电热壶有味怎么办 两个月狗耳朵臭怎么办 狗狗牙齿变黄怎么办 人用了狗沐浴露怎么办 狗狗吞食牙膏吐怎么办? 狗狗吞食了牙膏怎么办 大猪拉稀不吃食怎么办 猪不发烧不吃食怎么办 天天吃自热米饭怎么办 喝了加热包水怎么办啊 蛋挞没有盒子装怎么办 塑料饭盒盖子被吸住了怎么办 火腿淹的有臭味怎么办 微波炉热饭盖子打不开怎么办 夏天带饭容易馊怎么办? 保温饭盒里有气打不开怎么办 保温饭盒摔了一下打不开怎么办 饭盒跟盖子盖一起打不开怎么办 玻璃杯子盖被水吸住打不开怎么办 电饭煲热剩饭没加水怎么办 微波炉碗盖子吸住了怎么办 微波炉转饭盖子吸住了怎么办 玻璃碗放进微波炉打不开怎么办 乐扣微波炉加热后打不开怎么办 美的微波炉盖子打不开怎么办 美的微波炉门都打不开了怎么办 饭煮好了有异味怎么办 一正常吃饭就胖怎么办 高铁盒饭没15的怎么办 上火车前票丢了怎么办 减肥期吃了汉堡怎么办 寿司店鳗鱼有刺怎么办 吃泡面胃难受该怎么办 吃上火的东西脸上长痘痘怎么办 减肥期间吃撑了怎么办 喝了变质的牛奶怎么办 绿豆糕吃多了会怎么办 小孩抓米饭烫了手怎么办 减肥不来月经了怎么办