1123 铲雪车

解题报告:这题其实不知道欧拉路径也能做出来,由于铲雪车在路径上,那么只要算出来所有路径长*2,因为两边都要铲,除以速度就是答案了。

#include<iostream>
#include<cmath>
using namespace std;
double get_dis(int x1,int y1,int x2,int y2)
{
   
    return sqrt(1.0*(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main()
{
   
    int x,y;
    cin>>x>>y;
    double sum=0;
    int x1,y1,x2,y2;
    while(cin>>x1>>y1>>x2>>y2)
    {
   
        sum+=get_dis(x1,y1,x2,y2);
    }
    sum/=10000;
    int h=(int)sum;
    sum-=h;
    int m=sum*60+0.5;
    printf("%d:%02d\n",h,m);
    return 0;
}

1184.欧拉回路

解题报告:其实就是爆搜,从一个不是孤立的点开始爆搜,这里爆搜要有优化,&i就是为了改变h[u],这样删完边能从m^2的复杂度优化成m。最后在回溯的时候记录边的编号,再逆序输出才是真正的欧拉路径。

#include<iostream>
#include<cstring>
using namespace std;
const   int N=100010,M=400010;
int h[N],w[M],ne[M],idx,e[M];
int din[N],dout[N];
int cnt;
int ans[M/2];
int type;
int n,m;
bool st[M];
void add(int a,int b)
{
   
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u)
{
   
    for(int &i=h[u];~i;)	
    {
   
        if(st[i])
        {
   
            i=ne[i];
            continue;
        }
        st[i]=true;
        if(type==1)
        st[i^1]=true;
        int t;
        if(type==1)
        {
   
            t=i/2+1;
            if(i&1)   t=-t;
        }
        else
        t=i+1;
        int j=e[i];
        i=ne[i];
        dfs(j);
        ans[++cnt]=t;
    }
}
int main()
{
   
    scanf("%d",&type);
    memset(h,-1,sizeof h);
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
   
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);
        dout[a]++,din[b]++;
        if(type==1)
        add(b,a);
    }
    if(type==1)
    {
   
        for(int i=1;i<=n;i++)
        if(din[i]+dout[i]&1)    
        {
   
            puts("NO");
            return 0;
        }
    }
    else
    {
   
        for(int i=1;i<=n;i++)
        if(din[i]!=dout[i])
        {
   
            puts("NO");
            return 0;   
        }
    }
    for(int i=1;i<=n;i++)
    {
   
        if(h[i]!=-1)
        {
   
            dfs(i);
            break;
        }
    }
    if(cnt<m)
    {
   
        puts("NO");
        return 0;
    }
    puts("YES");
    for(int i=cnt;i;i--)
    printf("%d ",ans[i]);
    puts("");
    return 0;
}

AcWing 1124. 骑马修栅栏

解题报告:这题就是欧拉路径的无向图,由于没有special judge,我们就要想想如何输出字典序最小的欧拉路径,其实可以每次搜编号最小的点,然后逆序输出必定是字典序最小的。

#include<iostream>
#include<cstring>
using namespace std;
const   int N=510,M=1124;
int g[N][N];
int ans[M];
int cnt;
int d[N];
  int m;
  int n=500;
void dfs(int u)
{
   
    for(int i=1;i<=n;i++)
        if(g[u][i])
        {
   
            g[u][i]--;
            g[i][u]--;
            dfs(i);
        }
        ans[++cnt]=u;
}
int main()
{
   
  
    cin>>m;
    for(int i=0;i<m;i++)
    {
   
       int a,b;
       cin>>a>>b;
       g[a][b]++;
       g[b][a]++;
       d[a]++;
       d[b]++;
    }
    int start=1;
    while(!d[start])    start++;
    for(int i=1;i<=n;i++)
    if(d[i]%2)
    {
   
        start=i;
        break;
    }
    dfs(start);
    for(int i=cnt;i;i--)
    printf("%d\n",ans[i]);
    return 0;
}

这题只要判断是否存在有向图的欧拉路径就行了,如果只存在1个终点(入度比出度大一)和初点(入度比出度少一)或者0个(环的情况)就能存在了,并且图还要是联通的,判断图的连通性可以用并查集。

#include<iostream>
#include<cstring>
using namespace std;
const   int N=30;
bool st[N];
int din[N],dout[N];
char str[1100];
int p[N];
int find(int x)
{
   
    if(x!=p[x])
    p[x]=find(p[x]);
    return p[x];
}
int main()
{
   
    int T;
    cin>>T;
    while(T--)
    {
   
        memset(din,0,sizeof din);
        memset(dout,0,sizeof dout);
        memset(st,0,sizeof st);
        int n;
        scanf("%d",&n);
        for(int i=0;i<26;i++)
        p[i]=i;
        for(int i=0;i<n;i++)
        {
   
            scanf("%s",str);
        int len=strlen(str);
        int a=str[0]-'a',b=str[len-1]-'a';
        st[a]=true,st[b]=true;
        din[b]++,dout[a]++;
            p[find(a)]=find(b);
        }
        int end=0,start=0;
        bool flag=true;
        for(int i=0;i<26;i++)
        {
   
            if(st[i])
            {
   
                if(din[i]==dout[i]) continue;
                if(din[i]==dout[i]+1)   end++;
                else if(din[i]+1==dout[i])  start++;
                else flag=false;
            }
        }
        if(flag&&!(end==1&&start==1)&&!(end==0&&start==0))  flag=false;
        int t=-1;
        for(int i=0;i<26;i++)
        {
   
            if(st[i])
            {
   
                if(t==-1||find(i)==t)   t=find(i);
                else   
                {
   
                    flag=false;
                    break;
                }
            }
        }
        if(!flag)
        puts("The door cannot be opened.");
        else
        puts("Ordering is possible.");
        
        
    }
    return 0;
}