POJ 1639 最小度限制生成树(TLE,原因:未知)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41661919/article/details/84883583
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include<algorithm>
#include <set>
#include <queue>
#include <stack>
#include<vector>
#include<map>
#include<ctime>
#define ll long long
using namespace std;
const int N=36;
int v[N];//联通块标号

int ver[N];//邻接表边N的终点
int edge[N*N+100];//邻接表边N的权值
int head[N];//邻接表点N的最后一条边
int next[N];//邻接表边N的下一条边
int tot;//邻接表 中边数
int cnt;//联通块的数目


int ff1[N];
int ff2[N];
int ff3[N];
void add(int x,int y,int z)//邻接表加边
{
    ver[++tot]=y;
    edge[tot]=z;
    next[tot]=head[x];
    head[x]=tot;
}
void dfs(int x)//得到x所在的联通块
{
    v[x]=cnt;
    for(int i=head[x];i;i=next[i])
    {
        int y=ver[i];
        if(v[y])continue;
        dfs(y);
    }
}
int dis[N][N];
map<string,int>mm;
int num;
int d[N];//prime中以点N为终点的那条边;
bool flag[N];
int prime(int index,int pos,int nn)//联通块标号、起点
{
    for(int i=0;i<=32;++i)d[i]=999999999;
    memset(flag,0,sizeof(flag));
    d[pos]=0;
    for(int i=1;i<nn;++i)
    {

        int x=0;
        for(int j=1;j<=num;++j)
            if(!flag[j]&&((x==0)||d[j]<d[x])&&v[j]==index)x=j;
        flag[x]=1;
        for(int j=head[x];j;j=next[j])
        {
            int y=ver[j];
            if(!flag[y]&&v[y]==index)
            {
                if(edge[j]<d[y])
                {
                    d[y]=edge[j];
                    ff2[y]=x;
                }


                d[y]=min(d[y],edge[j]);
            }

        }
    }
    int ans=0;
    for(int i=1;i<=num;++i)
    {
        if(v[i]==index)ans+=d[i];
    }
    return ans;

}
int dfs2(int xx)//找1->xx的最长边
{
    int ans=0;
    for(int i=xx;i!=ff1[v[xx]];i=ff2[i])
    {
        ans=max(ans,dis[i][ff2[i]]);
    }
    return ans;

}
int main()
{
    int n;
    while(cin>>n)
    {
        memset(dis,0,sizeof(dis));
        tot=cnt=0;
        mm.clear();
        memset(v,0,sizeof(v));
        memset(ver,0,sizeof(ver));
        memset(head,0,sizeof(head));
        memset(next,0,sizeof(next));
        memset(edge,0,sizeof(edge));
        string str,t;
        int x;
        mm.insert(make_pair("Park",1 ));
        num++;
        for(int i=1;i<=n;++i)
        {
            cin>>str>>t>>x;
            int d1,d2;
            if(mm.find(str)==mm.end())
            {
                num++;
                mm.insert(make_pair(str,num));
                d1=num;

            }
            else
            {
                d1=mm.find(str)->second;
            }
            if(mm.find(t)==mm.end())
            {
                num++;
                mm.insert(make_pair(t,num));
                d2=num;
            }
            else
            {
                d2=mm.find(t)->second;
            }
            dis[d1][d2]=dis[d2][d1]=x;
            add(d1,d2,x);
            add(d2,d1,x);
        }

        int s;
        cin>>s;

        for(int i=2;i<=num;++i)
        {
            if(v[i])continue;
            cnt++;
            dfs(i);
        }
        //cout<<cnt<<".."<<endl;
        int ans=0;
        for(int i=1;i<=cnt;++i)
        {

            int minn=999999999;
            int pos;
            int nn;
            for(int j=1;j<=num;++j)
            {
                int nn=0;
                if(v[j]==i)
                {
                    nn++;
                    if(dis[j][1]<minn)minn=dis[j][1],pos=j;
                }
            }
            if(minn!=999999999)ans+=minn;
            ans+=prime(i,pos,nn);
            ff1[i]=pos;
        }
        //cout<<ff1[cnt]<<endl;
        int kk=cnt;
        for(int j=head[1];j;j=next[j])
        {
            int xx=ver[j];//边的终点
            int vv=dfs2(xx);
            if(edge[j]<vv)
            {
                //cout<<edge[j]<<" "<<vv<<endl;
                ans=ans+edge[j]-vv;
                kk++;
                if(kk==s)break;

            }

        }
        cout<<"Total miles driven: "<<ans<<endl;
    }

}
//提交时稍作修改,scanf......
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include<algorithm>
#include <set>
#include <queue>
#include <stack>
#include<vector>
#include<map>
#include<ctime>
#define ll long long
using namespace std;
const int N=36;
const int M=36*36;
int v[N];//联通块标号

int ver[M];//邻接表边M的终点
int edge[N*N];//邻接表边M的权值
int head[N];//邻接表点N的最后一条边
int next[M];//邻接表边M的下一条边
int tot;//邻接表 中边数
int cnt;//联通块的数目


int ff1[N];
int ff2[N];
int ff3[N];
void add(int x,int y,int z)//邻接表加边
{
    ver[++tot]=y;
    edge[tot]=z;
    next[tot]=head[x];
    head[x]=tot;
}
void dfs(int x)//得到x所在的联通块
{
    v[x]=cnt;
    for(int i=head[x];i!=-1;i=next[i])
    {
        int y=ver[i];
        if(v[y])continue;
        dfs(y);
    }
}
int dis[N][N];
map<string,int>mm;
int num;
int d[N];//prime中以点N为终点的那条边;
bool flag[N];
int prime(int index,int pos,int nn)//联通块标号、起点
{
    memset(d,0x3f,sizeof(d));
    memset(flag,0,sizeof(flag));
    d[pos]=0;
    for(int i=1;i<nn;++i)
    {

        int x=0;
        for(int j=1;j<=num;++j)
            if(!flag[j]&&((x==0)||(d[j]<d[x]))&&v[j]==index)x=j;
        flag[x]=1;
        for(int j=head[x];j!=-1;j=next[j])
        {
            int y=ver[j];
            if(!flag[y]&&v[y]==index)
            {
                if(edge[j]<d[y])
                {
                    d[y]=edge[j];
                    ff2[y]=x;
                }


                d[y]=min(d[y],edge[j]);
            }

        }
    }
    int ans=0;
    for(int i=1;i<=num;++i)
    {
        if(v[i]==index)ans+=d[i];
    }
    return ans;

}
int dfs2(int xx)//找1->xx的最长边
{
    int ans=0;
    for(int i=xx;i!=ff1[v[xx]];i=ff2[i])
    {
        ans=max(ans,dis[i][ff2[i]]);
    }
    return ans;

}
char ch1[110];
char ch2[110];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(dis,0,sizeof(dis));
        tot=cnt=0;
        mm.clear();
        memset(v,0,sizeof(v));
        memset(ver,0,sizeof(ver));
        memset(head,0,sizeof(head));
        memset(next,-1,sizeof(next));
        memset(edge,0,sizeof(edge));
        string str,t;
        int x;
        mm.insert(make_pair("Park",1 ));
        num++;
        getchar();
        for(int i=1;i<=n;++i)
        {
            scanf("%s",ch1);
           getchar();
            scanf("%s",ch2);
            getchar();
            scanf("%d",&x);
            str=ch1;
            t=ch2;
            //cin>>str>>t>>x;
            int d1,d2;
            if(mm.find(str)==mm.end())
            {
                num++;
                mm.insert(make_pair(str,num));
                d1=num;

            }
            else
            {
                d1=mm.find(str)->second;
            }
            if(mm.find(t)==mm.end())
            {
                num++;
                mm.insert(make_pair(t,num));
                d2=num;
            }
            else
            {
                d2=mm.find(t)->second;
            }
            dis[d1][d2]=dis[d2][d1]=x;
            add(d1,d2,x);
            add(d2,d1,x);
        }

        int s;
        scanf("%d",&s);

        for(int i=2;i<=num;++i)
        {
            if(v[i])continue;
            cnt++;
            dfs(i);
        }
        //cout<<cnt<<".."<<endl;
        int ans=0;
        for(int i=1;i<=cnt;++i)
        {

            int minn=0X3F;
            int pos;
            int nn;
            for(int j=1;j<=num;++j)
            {
                int nn=0;
                if(v[j]==i)
                {
                    nn++;
                    if(dis[j][1]<minn)minn=dis[j][1],pos=j;
                }
            }
            if(minn!=999999999)ans+=minn;
            ans+=prime(i,pos,nn);
            ff1[i]=pos;
        }
        //cout<<ff1[cnt]<<endl;
        int kk=cnt;
        for(int j=head[1];j!=-1;j=next[j])
        {
            int xx=ver[j];//边的终点
            int vv=dfs2(xx);
            if(edge[j]<vv)
            {
                //cout<<edge[j]<<" "<<vv<<endl;
                ans=ans+edge[j]-vv;
                kk++;
                if(kk==s)break;

            }

        }
        printf("Total miles driven: %d\n",ans);
        //cout<<""<<ans<<endl;
    }
    return 0;

}

猜你喜欢

转载自blog.csdn.net/qq_41661919/article/details/84883583
今日推荐