SDUT 2838 Word ladder 图的直径

来源:互联网 发布:北师珠网络登录 编辑:程序博客网 时间:2024/06/05 14:53

昨天周赛H题。。。当时第一发的时候手残了,改正之后发现好像题意不太对,感觉是找最长的一条没有重点的链,又是一张有环的图,不会做,果断放弃去切了另外一个题。之后也没有再读题,也没有分析样例。。。。直到赛后学姐说是找最短路中的最长路,我才发现自己跑偏了。。

也就是说,设P(i,j) 表示 i 到 j 的最短路的长度,则答案为 anw = max( p(i,j) )(i != j)。其实此时 anw 就是图的直径的长度。

其实当时最开始的思路是对的。。。今天按照那个思路写了一遍直接1A了。。当时要是拉着胖胖读一遍题就好了。。

把给出的字符串看成图中对应的结点,则字符串 i 若能通过给出的规则改变且改变一次变成字符串 j ,则说对应的结点i,j有一条边相连。

剩下的就是两次BFS寻找直径的问题了。

对于一个联通的无向图,从任意一点开始BFS,则最后加入队列里的点必为直径的一个端点,然后再从这个端点出发,则最后的那个点即为直径的另一个端点。

但是不知道证明过程。。。这个坑以后再补吧。。。

#include <iostream>#include <algorithm>#include <cstdlib>#include <cstdio>#include <cstring>#include <queue>#include <cmath>#include <stack>#pragma comment(linker, "/STACK:1024000000");#define EPS (1e-6)#define LL long long#define ULL unsigned long long int#define _LL __int64#define _INF 0x3f3f3f3f#define Mod 1000000007using namespace std;char s[510][51];int len[510];bool Match(int u,int v){    if(abs(len[u]-len[v]) >= 2)        return false;    if(len[u] == len[v])    {        int i,ans;        for(i = 0,ans = 0;i < len[u]; ++i)        {            if(s[u][i] != s[v][i])            {                ans++;                if(ans >= 2)                    return false;            }        }    }    else    {        if(len[u] > len[v])            swap(u,v);        int i,j;        for(i = 0,j = 0;i < len[u] && j < len[v];)        {            if(s[u][i] == s[v][j])            {                ++i,++j;            }            else            {                ++j;                if(abs(i-j) >= 2)                    return false;            }        }        if(abs(i-j) >= 2)            return false;    }    return true;}struct N{    int u,v,next;}edge[250010];int Top;int head[510];void Link(int u,int v){    edge[Top].u = u;    edge[Top].v = v;    edge[Top].next = head[u];    head[u] = Top++;}bool m1[510],m2[510];int endpoint,TempLength;struct Q{    int v,ans;};void bfs1(int x){    queue<Q> q;    Q s,f;    s.ans = 1;    s.v = x;    m1[x] = true;    q.push(s);    while(q.empty() == false)    {        f = q.front();        q.pop();        endpoint = f.v;        TempLength = f.ans;        for(int p = head[f.v];p != -1; p = edge[p].next)        {            if(m1[edge[p].v] == false)            {                m1[edge[p].v] = true;                s.ans = f.ans+1;                s.v = edge[p].v;                q.push(s);            }        }    }}void bfs2(int x){    queue<Q> q;    Q s,f;    s.ans = 1;    s.v = x;    m2[x] = true;    q.push(s);    while(q.empty() == false)    {        f = q.front();        q.pop();        endpoint = f.v;        TempLength = f.ans;        for(int p = head[f.v];p != -1; p = edge[p].next)        {            if(m2[edge[p].v] == false)            {                m2[edge[p].v] = true;                s.ans = f.ans+1;                s.v = edge[p].v;                q.push(s);            }        }    }}int main(){    int n,i,j;    while(scanf("%d",&n) && n)    {        for(i = 0;i < n; ++i)        {            scanf("%*c%s",s[i]);            len[i] = strlen(s[i]);        }        memset(head,-1,sizeof(int)*(n+3));        Top = 0;        for(i = 0;i < n; ++i)        {            for(j = i+1;j < n; ++j)            {                if(Match(i,j))                {                    Link(i,j);                    Link(j,i);                }            }        }        memset(m1,false,sizeof(bool)*(n+3));        memset(m2,false,sizeof(bool)*(n+3));        int Max = 1;        for(i = 0;i < n; ++i)        {            if(m1[i] == false)            {                bfs1(i);                bfs2(endpoint);                Max = max(Max,TempLength);            }        }        printf("%d\n",Max);    }    return 0;}

0 0
原创粉丝点击