hdu 4756 & hdu 4126 & hdu 4081

         hdu 4756是南京网赛的题,这题和2011年福州现场赛的一道题,也就是hdu4126很像,比赛前十几天明明做过的说,结果比赛的时候没看到这题,唉。今天一不小心又翻到了一个和这两题也很像的题——hdu 4081,还是2011北京现场赛的题,晕了,既然这样就直接都放在一起算了。

 

        这三个题思路都差不多,问题都是先要求一个最小生成树,然后删掉一条边,询问剩下的最小生成树的情况(距离或者两点权值和之类的)。方法基本都是这样的:求完最小生成树以后,用dp[u][v]表示把最小生成树的边(u,v)切断以后,在两个子树中连某条边能得到的最好情况(这里以删除一条边以后剩下最小生成树的权值为例吧)。以一个点p为父节点,然后对于一条边(u,v),可以算出v及v的子树中某一点和p连边能获得的最小权值。这样将n个点都搜一遍就行了,然后根据题中的意思进行计算结果就行了。

 

      hdu 4756 Install Air Conditioning

     

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=1000+10;
const double INF=1e18;
struct Edge
{
    int u,v,next;
};
struct Points
{
    int x,y;
};
Points points[maxn];
Edge edges[maxn<<1];
int head[maxn],pa[maxn],nEdge;
void AddEdge(int u,int v)
{
    nEdge++;
    edges[nEdge].u=u;
    edges[nEdge].v=v;
    edges[nEdge].next=head[u];
    head[u]=nEdge;
}
double ways[maxn][maxn],dp[maxn][maxn],d[maxn];
bool vis[maxn];
void Init(int n)
{
    for(int i=0;iways[pos][k])
            {
                d[k]=ways[pos][k];
                pa[k]=pos;
            }
        }
    }
    return res;
}
double dfs(int u,int fa,int p)
{
    double res=INF;
    for(int k=head[u];k!=-1;k=edges[k].next)
    {
        int v=edges[k].v;
        if(v==fa) continue;
        double tmp=dfs(v,u,p);
        res=min(tmp,res);
        dp[u][v]=dp[v][u]=min(dp[u][v],tmp);
    }
    if(fa!=p)
      res=min(res,ways[u][p]);
    return res;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int t,n,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&k);
        Init(n);
        for(int i=0;i

 

 

hdu 4126 Genghis Khan the Conqueror

 

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=3000+10;
struct Edge
{
    int v;
    int next;
};
Edge edges[maxn<<1];
int head[maxn],nEdge;
int way[maxn][maxn],dis[maxn],pa[maxn],dp[maxn][maxn];
bool vis[maxn];
int n,m;
void clearAll()
{
    memset(vis,0,sizeof(vis));
    memset(head,0xff,sizeof(head));
    for(int i=0;i


 

 

hdu 4081 Qin Shi Huang's National Road System

 

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=1000+10;
const double INF=1e10;
struct Edge
{
    int u,v,next;
};
struct Point
{
    int x,y;
}points[maxn];
Edge edges[maxn<<1];
int head[maxn],nEdge;
void AddEdge(int u,int v)
{
    nEdge++;
    edges[nEdge].u=u;
    edges[nEdge].v=v;
    edges[nEdge].next=head[u];
    head[u]=nEdge;
}
double Len(Point a,Point b)
{
    return sqrt((double)(a.x-b.x)*(a.x-b.x)+(double)(a.y-b.y)*(a.y-b.y));
}
int n,val[maxn],pa[maxn],dp[maxn][maxn];
double ways[maxn][maxn],d[maxn],ans,prval;
bool vis[maxn];
void prime()
{
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;++i) d[i]=ways[1][i],pa[i]=1;
    vis[1]=true;pa[1]=-1;prval=0;
    double minval;
    int pos;
    for(int i=1;iways[pos][k])
            {
                d[k]=ways[pos][k];
                pa[k]=pos;
            }
        }
    }
}
int dfs(int u,int fa,int p)
{
    int res=0;
    for(int k=head[u];k!=-1;k=edges[k].next)
    {
        int v=edges[k].v;
        if(v==fa) continue;
        int tmp=dfs(v,u,p);
        res=max(res,tmp);
        dp[u][v]=dp[v][u]=max(dp[u][v],tmp);
    }
    if(u!=p)
      res=max(res,val[u]+val[p]);
    return res;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
           scanf("%d%d%d",&points[i].x,&points[i].y,&val[i]);
        for(int i=1;i<=n;++i)
          for(int j=i;j<=n;++j)
             ways[i][j]=ways[j][i]=Len(points[i],points[j]);
        memset(head,0xff,sizeof(head));
        nEdge=-1;
        prime();
        ans=0;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;++i)
          dfs(i,-1,i);
        int u,v;
        for(int i=0;i<=nEdge;i+=2)
        {
            u=edges[i].u;v=edges[i].v;
            ans=max(ans,(dp[u][v])/(prval-ways[u][v]));
        }
        printf("%.2lf\n",ans);
    }
    return 0;
}



 

你可能感兴趣的:(并查集,dfs)