您的位置:首页 > 其它

EOJ Monthly 2018.1 F1. 最小 OR 路径 (EASY) 新的建图方式+vis同时记录点和代价

2018-01-23 15:26 246 查看
Memory limit: 512 megabytes

给定一个有
n
个点和
m
条边的无向图,其中每一条边
ei
都有一个权值记为
wi。

对于给出的两个点
a

b,求一条

a

b
的路径,使得路径上的边权的 OR(位或)和最小,输出这个值。(也就是说,如果将路径看做边的集合
{e1,e2,…,ek},那么这条路径的代价为

w1ORw2OR…ORwk,现在求一条路径使得其代价最小,输出这个代价。)
如果不存在这样的路径,输出
−1。

Input

第一行两个数
n

m。

接下来
m
行,每行三个数
ui,vi,wi,表示有一条

ui

vi
的权值为
wi
的无向边。

最后一行两个数
a,b,分别表示起点和终点。

2≤n≤103,0≤m≤104,0≤ci≤210−1

1≤ui,vi,a,b≤n,a≠b

可能有重边和自环。

Output

在一行中输出一个最小代价,如果无解输出
−1。

Examples

Input
3 4
1 2 2
1 2 4
1 3 5
2 3 3
1 2


Output
2


Note

图中可能会有重边。

用DFS。

建图的时候一开始用的邻接表,结果我们在枚举某个点指向的各个点时,我们还需要两者之间边的信息(w)。用邻接表只能获得点,所以不行。

而数组也更不可以,因为有重边。

所以用 vector< pair<int,int> >Edge[n+1]; 来存放。可以获得点和边的信息。

建立一个vis【a】【b】,记录到达a点时,代价为b是否存在。

利用bfs,建立两个queue,一个存放点(当前到达了那个点),一个存放代价(到达当前点是的代价为多少)。

我们遍历下一个点,vis[a][b|w]=1。不管三七二十一把所有的情况都遍历完。

之后我们代价从1-1024开始枚举。

找最小代价,也就是到达vis[b][i]。如果存在,那么输出i,break即可。

#include <bits/stdc++.h>

using namespace std;

int main()

{

    int n,m;

    bool vis[1100][1100];

    cin>>n>>m;

    vector< pair<int,int> >Edge[n+1];

    for(int i=0;i<m;i++)

    {

        int a,b,c;

        cin>>a>>b>>c;

        Edge[a].push_back(make_pair(b,c));

        Edge[b].push_back(make_pair(a,c));

    }

    int a,b;

    cin>>a>>b;

    memset(vis,false,sizeof(vis));

    vis[a][0]=true;

    queue<int>que1;

    queue<int>que2;

    que1.push(a);

    que2.push(0);

    while(!que1.empty())

    {

        int qu1=que1.front();

        int qu2=que2.front();

        que1.pop();

        que2.pop();

        for(pair<int,int>b:Edge[a])

        {

             pair<int,int>dangqian=b;

             if(!vis[dangqian.first][qu2|dangqian.second])

             {

                 vis[dangqian.first][qu2|dangqian.second]=true;

                 que1.push(dangqian.first);

                 que2.push(dangqian.second|qu2);

             }

        }

    }

    int flag=0;

    for(int i=1;i<=n;i++)

    {

        if(vis[b][i])

        {

            cout<<i<<endl;

            flag=1;

            break;

        }

    }

    if(flag)

    {

    }

    else

    {

        cout<<"-1"<<endl;

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: