UVA 10681

来源:互联网 发布:java 计算bmi 编辑:程序博客网 时间:2024/06/05 02:30

Problem A - Teobaldo's Trip

Time Limit: 1 second

Memory Limit: 1 Mb

Teobaldo works for the Brazilian government. In his job, he travels a lot. When Teolbaldo travels from a city S to a city E he can spend up to D days in the trip.

As Teobaldo doesn't like to work, he always spend the maximum number of days in his trips. In each day of his trip, Teobaldo sleeps in a different city from the previous day, because he thinks it is boring to stay in the same city two consecutive days.

In this problem, you should help Teobaldo to schedule his trips.

Input

The input file contains several input sets. The description of each set is given below:

Each set starts with two integers C (0 < C ≤ 100), the number of cities, and L (0 ≤ L ≤ 500), the number of links between the cities. Follow L lines, where each line has two numbers: A and B (1 ≤ A,B ≤ C), meaning there is a link between these two cities. You can assume that A and B are different numbers. After the L lines, there are three integers: S,E and D. Where S is the city where the trip must start, E is the city where the trip must end, and D (0 ≤ D ≤ 200) is the maximum number of days for Teobaldo to go from S to E.

Input is terminated by a set where C=L=0. This set should not be processed. There is a blank line beteween two input sets.

Output

For each input set produce one line of output, indicating if Teobaldo can travel how he wishes. See the examples below for the exact input/output format.

Sample Input

3 21 22 33 1 23 21 21 31 3 20 0

Sample Output

Yes, Teobaldo can travel.No, Teobaldo can not travel.


Problem setter: S�rgio Queiroz de Medeiros



有一个人去旅行,他连续两天不能住相同的城市,问他能不能用d天从s城到e城。稍微补充一下题目未交待清楚的地方。

1、从一个城市到与之相邻的城市需要花1天的时间。

2、第d天必须在e城,可以提前到,但是第d天必须在e城,且不能在一个城市连续呆两天,也就是说提前到了还要离开等到第e天再到。

因此本题就是:如果把城市间的距离看成1,是否存在从s到e长为k的有向链。

定义:A是图G的邻接矩阵,则A中a[i][j],表示图G中i到j的有向边的数目。(无向边视为两条有向边)


定理:假设A为图G的邻接矩阵,则A^k中的a[i][j]表示从i到j长为k的有向链数目。


证明:

1、当k=1时,由定义,结论显然成立。

2、假设k-1时结论成立,A^k=A*A^(k-1)

有 a[i][j](k)=sum(a[i][t](k-1)*a[t][j]) a[i][j](x)表示A^x中的a[i][j]

a[i][t](k-1)是长为k-1的链,在加上t到j这一段就生成了长为k的链。


本题就是求A^d,用矩阵快速幂。但是这样的链会很多,会爆精度,我们只关心有没有,所有把矩阵乘法中的+改为|,*改为&即可。


#include<cstdio>#include<string>#include<cstring>#define maxn 109using namespace std;int n,m;int a[maxn][maxn],ans[maxn][maxn];void muti(int a[maxn][maxn],int b[maxn][maxn],int c[maxn][maxn]){    int tmp[maxn][maxn];    memset(tmp,0,sizeof(tmp));    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)            for(int k=1;k<=n;k++)    tmp[i][j]|=a[i][k]&b[k][j];    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)        c[i][j]=tmp[i][j];}void mgml(int b){    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)    {        if(i==j)ans[i][j]=1;        else ans[i][j]=0;    }    while(b)    {        if(b&1)        {            muti(ans,a,ans);        }        muti(a,a,a);        b>>=1;    }}int main(){    while(1)    {        scanf("%d%d",&n,&m);        if(!n&&!m)break;        memset(a,0,sizeof(a));        for(int i=0;i<m;i++)        {            int x,y;            scanf("%d%d",&x,&y);            a[x][y]=a[y][x]=1;        }        int s,e,d;        scanf("%d%d%d",&s,&e,&d);        mgml(d);        if(ans[s][e])printf("Yes, Teobaldo can travel.\n");        else printf("No, Teobaldo can not travel.\n");    }}