日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

A - Wireless Network-poj2236(简单并查集)

發(fā)布時(shí)間:2023/10/11 综合教程 99 老码农
生活随笔 收集整理的這篇文章主要介紹了 A - Wireless Network-poj2236(简单并查集) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
說(shuō)是有N個(gè)村莊,剛開(kāi)始每個(gè)村莊的網(wǎng)絡(luò)都是受損狀態(tài),于是派一個(gè)人去修理,修理過(guò)的村莊只能聯(lián)系距離他們半徑為D的村莊,當(dāng)然他們可以通過(guò)一些村莊當(dāng)中轉(zhuǎn)站,聯(lián)系。
 
輸入先輸入一個(gè)N表示有N個(gè)村莊,還有一個(gè)D表示每個(gè)村莊的最大通訊半徑,接著有一系列的修復(fù)操作和查詢(xún)操作,如果兩個(gè)地方不通那么很明顯應(yīng)該輸出FALL,否則SUCCESS。
 
題意已經(jīng)很明確了,就是修復(fù)查詢(xún),修復(fù)好一個(gè)點(diǎn)后與其他修復(fù)后的點(diǎn)對(duì)比一下看看是否能連接成功。
 
 
/////////////////////////////////////////////////////////////////////////
時(shí)間用了3S,懶得優(yōu)化了,優(yōu)化方法可以搞一個(gè)數(shù)組轉(zhuǎn)來(lái)保存已經(jīng)修復(fù)的額點(diǎn),這樣判斷起來(lái)少了很多冗余
 
#include<stdio.h>

const int maxn  = ;

struct node
{
    int x, y, ok;
}p[maxn];//保存所有的村莊,ok表示是否已經(jīng)修復(fù) int f[maxn]; int Len(node a, node b)//求兩個(gè)村莊的距離
{
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int Find(int x)
{
    if(f[x] != x)
        f[x] = Find(f[x]);
    return f[x];
} int main()
{
    int i, N, D, u, v;
    char s[];     scanf("%d%d", &N, &D);     D = D*D;//因?yàn)榫嚯x只做判斷,所以直接用平方數(shù)判斷更準(zhǔn)確,避免小數(shù)     for(i=; i<=N; i++)
    {
        scanf("%d%d", &p[i].x, &p[i].y);
        p[i].ok = ;
        f[i] = i;
    }     while(scanf("%s", s) != EOF)
    {
        if(s[] == 'O')
        {
            scanf("%d", &u);             if(p[u].ok == )
            {
                p[u].ok = ;
                for(i=; i<=N; i++)
                {
                    if(u != i && p[i].ok && Len(p[i], p[u]) <= D)
                    {
                        v = Find(i);
                        int k = Find(u);
                        f[k] = v;
                    }
                }
            }         }
        else
        {
            scanf("%d%d", &u, &v);
            u = Find(u);
            v = Find(v);             if(u != v)
                printf("FAIL\n");
            else
                printf("SUCCESS\n");
        }
    }     return ;

}

重構(gòu)了一下代碼,試圖弄出來(lái)并查集的模版,不過(guò)不是太理想

#include<stdio.h>

const int maxn = 1e3+;

struct FindSets
{
int *Father, size; FindSets(int size)
: size(size)
{
Father = new int[size+];
for(int i=; i<=size; i++)
Father[i] = i;
}
~FindSets()
{
delete[] Father;
}
int Find(int x)
{
if(Father[x] != x)
Father[x] = Find(Father[x]);
return Father[x];
}
bool connect(int u, int v, bool need)
{///判斷兩個(gè)點(diǎn)是否相連,如果需要相連則連接
u = Find(u);
v = Find(v);
if(need == true)
Father[v] = u;
return u == v;
}
}; struct point
{
int x, y, fine;
}; bool Dis(point &a, point &b, int D)
{///判斷兩點(diǎn)之間的距離是否大于D
return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)) <= D*D;
} void Repair(int u, int D, point p[], FindSets &fs)
{///修復(fù)點(diǎn)u
for(int i=; i<=fs.size; i++)
{
if(p[i].fine == true && Dis(p[i], p[u], D))
fs.connect(i, u, true);
}
p[u].fine = true;
} int main()
{
int N, D; scanf("%d%d", &N, &D); FindSets fs(N);
point *p = new point[N+](); for(int i=; i<=N; i++)
scanf("%d%d", &p[i].x, &p[i].y); int u, v;
char op[]; while(scanf("%s", op) != EOF)
{
if(op[] == 'O')
{
scanf("%d", &u);
Repair(u, D, p, fs);
}
else
{
scanf("%d%d", &u, &v);
if(fs.connect(u, v, false) == true)
printf("SUCCESS\n");
else
printf("FAIL\n");
}
} delete[] p; return ;
}

總結(jié)

以上是生活随笔為你收集整理的A - Wireless Network-poj2236(简单并查集)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。