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

  • Post author:
  • Post category:其他



Memory limit:

512 megabytes

给定一个有








n









个点和








m









条边的无向图,其中每一条边












e





i












都有一个权值记为












w





i












对于给出的两个点








a


















b









,求一条








a


















b









的路径,使得路径上的边权的 OR(位或)和最小,输出这个值。(也就是说,如果将路径看做边的集合








{








e





1






,







e





2






,





,







e





k






}









,那么这条路径的代价为













w





1










O


R











w





2










O


R













O


R











w





k













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











1









Input

第一行两个数








n


















m











接下来








m









行,每行三个数













u





i






,







v





i






,







w





i













,表示有一条












u





i

























v





i












的权值为












w





i












的无向边。

最后一行两个数








a


,


b









,分别表示起点和终点。









  • 2





    n










    10





    3






    ,


    0





    m










    10





    4






    ,


    0










    c





    i














    2







    10











    1
















  • 1










    u





    i






    ,







    v





    i






    ,


    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;

}

}



版权声明:本文为Little_boy_z原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。