您的位置:首页 > 其它

UVALive 7414 Sibling Rivalry

2016-08-28 14:18 218 查看
题意:n个点m条边的有向图,有一个起点和一个终点,每次兄贵选择从abc三个数中选择一个数作为你前进的步数,问兄贵最多选择多少次你一定可以到达终点,如果无论如何都到大不了终点则输出IMPOSSIBLE.

分析:假设最多需要k步我们一定可以到达终点,那么对于k-1步来说,他下一步走a,b,c步一定都可以到达终点,同理,k-2步的点下一步走a,b,c步一定可以到达k-1之前能到达的点,所以我们可以一遍bfs,如果结束了还没有找到起点,那么一定是无解。

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
#include <unordered_map>
#define INF 0x3f3f3f3f
#define eps 1e-9
#define MOD 1000000007
using namespace std;
typedef long long ll;
int n,m,a,b,c,jud[51],color[51],val[51];
struct Matrix
{
ll val[51][51];
int x,y;
friend Matrix operator *(const Matrix a,const Matrix b)
{
Matrix c = {0};
c.x = a.x,c.y = b.y;
for(int i = 1;i <= a.x;i++)
for(int j = 1;j <= b.y;j++)
for(int k = 1;k <= b.x;k++)
c.val[i][j] = (c.val[i][j] + a.val[i][k]*b.val[k][j]) % MOD;
return c;
}
}G,Ga,Gb,Gc;
Matrix ksm(Matrix a,ll b)
{
Matrix c = a;
b--;
while(b)
{
if(b & 1) c = c*a;
a = a*a;
b>>=1;
}
return c;
}
int main()
{
while(~scanf("%d%d%d%d%d",&n,&m,&a,&b,&c))
{
G.x = G.y = n;
memset(G.val,0,sizeof(G.val));
memset(jud,0,sizeof(jud));
memset(color,0,sizeof(color));
for(int i = 1;i <= m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
G.val[y][x] = 1;
}
Ga = ksm(G,a),Gb = ksm(G,b),Gc = ksm(G,c);
deque <int> s;
s.push_back(n);
jud
= true;
val
= 0;
while(!s.empty() && !jud[1])
{
int u = s.front();
s.pop_front();
for(int v = 1;v <= n;v++)
{
if(jud[v]) continue;
if(Ga.val[u][v]) color[v] |= 1;
if(Gb.val[u][v]) color[v] |= 2;
if(Gc.val[u][v]) color[v] |= 4;
if(color[v] == 7)
{
jud[v] = true;
val[v] = val[u] + 1;
if(v == 1) break;
s.push_back(v);
}
}
}
if(!jud[1]) cout<<"IMPOSSIBLE"<<endl;
else cout<<val[1]<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: