Luogu P1341 无序字母对

  突然发现我现在很喜欢打图论题。

  然而都是很easy的。

  这道题很坑,用C++打了一遍莫名Too many or too few lines。

  然后我打出了我的独门绝技Pascal。这可能是我最后一次用Pascal了。

  开始讲思路。

  首先每两点必须相连但无关方向,然后我们发现,可以跑一遍哈密顿回路来搞出答案。

  记录与每个点相连的边。

  统计一下向连边为奇数的点的个数。

  0个:找一个字典序最小的点dfs

  2:个:在两个奇点里找一个字典序最小的dfs

  其他:无解

  dfs时尽量选字典序小的,贪心即可

  由于范围小就用邻接矩阵来存了(f[i,j]表示i,j有边相连,e[i]为i点的相连边数)

  CODE

    uses math;
    var
        e:array[0..60*60+10] of longint;
        f:array[0..60,0..60] of boolean;
            i,j,n,minn,u,v,t,tot:longint;
        x,y:char;
        ans:array[0..60*60+10] of char;
    procedure dfs(k:longint);
    var i:longint;
    begin
    for i:=0 to 60 do
    if f[k,i] then
    begin f[k,i]:=false; f[i][k]:=false;
        dfs(i); end;
    inc(tot); ans[tot]:=chr(k+ord('A'));
    end;
    begin
    readln(n); minn:=2147483647;
    for i:=1 to n do
    begin readln(x,y); u:=ord(x)-ord('A'); v:=ord(y)-ord('A');
        minn:=min(minn,min(u,v));
        f[u,v]:=true; f[v,u]:=true;
        inc(e[u]); inc(e[v]); end;
    for i:=0 to 60 do
    if e[i] mod 2=1 then inc(t);    
    if t=0 then dfs(minn) else
    if t=2 then begin minn:=2147483647; for i:=0 to 60 do if e[i] mod 2=1 then minn:=min(minn,i); dfs(minn); end else
    begin writeln('No Solution'); halt; end;
    for i:=tot downto 1 do write(ans[i]);
    end.

 

  发一把C++的,只有10分被狗了(应该是输入输出的问题)。

  CODE

#include<cstdio>
#include<iostream>
using namespace std;
const int N=205;
int n,i,e[N],t,tot;
bool f[N][N];
char ans[N];
void dfs(int k)
{
    for (int i=0;i<=N;++i)
    if (f[k][i])
    {
        f[k][i]=f[i][k]=0;
        dfs(i);
    }
    ans[++tot]=k;
}
int main()
{
    //freopen("testdata.in","r",stdin); freopen("luogu.out","w",stdout);
    scanf("%d",&n); getchar();
    for (i=1;i<=n;++i)
    {
        char x=getchar(),y=getchar();
        getchar();
        f[x][y]=f[y][x]=1;
        e[x]++; e[y]++;
    }
    for (i=0;i<=N;++i)
    if (e[i]%2) t++;
    if (t==2) 
    {
        int x1,x2;
        for (i=0;i<=N;++i)
        if (e[i]%2) { x1=i; break; }
        for (i+=1;i<=N;++i)
        if (e[i]%2) { x2=i; break; }
        dfs(min(x1,x2));
    } else if (t==0)
    {
        for (i=0;i<=N;++i)
        if (e[i]) break;
        dfs(i);
    } else { puts("No Solution"); return 0; }
    for (i=tot;i;--i)
    printf("%c",ans[i]);
    return 0;
}

 

  %%%

posted @ 2017-11-30 07:08  空気力学の詩  阅读(185)  评论(0编辑  收藏  举报