NOI2003 智破連環陣

2021-07-12 06:41:27 字數 2696 閱讀 8424

先甩兩個**:

這是樓教主的 用的 部分搜尋 + 匹配   **飛快比較神

演算法合集之《**部分搜尋+高效演算法在搜尋問題中的應用

這是朱澤園的算是 面向資料程式設計..  用的 貪心搜尋+各種剪枝(但用的剪枝還是比樓教主的少)

zplhz_智破連環陣

我寫的 朱澤園的演算法 自己對著資料卡過去的 剪枝真是神啊

乙個我感覺沒啥用的剪枝可以直接把**從 30 變成 80

詳見**注釋

#include #include #include using namespace std;

int rank[101][101];

int lenth[101][101];

int ax[101],ay[101];

int bx[101],by[101];

int n,m,k;

void f(int x,int s,int t)

int cmpx;

bool cmp(int a,int b)

bool can(int boom,int arms)

bool used[101];

int tail[101];

int ans=1000000000;

void dfs(int now,int cnt,int cnt3)

int kcnt=0;

for(int i=1;i<=m&&kcnt!=3;i++)

if(!used[rank[now][i]]&&lenth[now][rank[now][i]]!=0) }

int main() }

for(int i=1;i<=n;i++)

for(int i=n;i>=1;i--)

tail[i]=tail[i+lenth[i][rank[i][1]]]+1;

dfs(1,0,1); //此處面向資料 只給了乙個 使用3 的機會

cout<

在加乙個樓教主的**** 我沒有格式化 自己邊看邊格式化吧 (我把第二部分的輸出方案給注釋掉了)

#include #include #include const int maxm=100+2;

const int maxn=100+2;

int n,m,dist[maxm],maxt[maxm][maxn];

bool reachable[maxm][maxn],*can[maxm][maxm];

/*m=b 國**數。

n=a 國炸彈數。

dist[i]=如果 a 國炸彈可以重複使用,炸掉 b 國** i~m 的最少使用炸彈數。

maxt[s][i]=炸彈 i,從 s 開始炸,可以炸到的最大編號,

如果炸彈 i 炸不到 s,則 maxt[i][s]=s-1。

reachable[i][j]=a國炸彈 i 是否可以炸到 b 國炸彈 j。

can[s][t][i]=表示 a 國炸彈 i 是否可以炸到 b 國** s,s+1..t-1,t。

*/int answer,bestv[maxn];

/*answer=最少需要的 a 國炸彈數。

bestv=記錄取最優解 a 國炸彈的使用序列。

*/int a[maxm],b[maxn];

bool vis[maxn],*g[maxm];

/*a[i],b[i]用於匹配,分別記錄左(右)第 i 個點的匹配邊的另乙個點的編號,如果沒有匹配

則為 0。

vis[i]用於匹配和寬度優先搜尋時判重。

g[i][j]=左邊第 i 個點到右邊第 j 個點是否有邊。

*/void init()

void preprocess()

}//計算 dist

dist[m+1]=0;

for (s=m;s>=1;s--)

}bool find(int v)

}return false;

}void search(int used,int s)

int t,maxl,tempa[maxm],tempb[maxn],op,cl,queue[maxn],k,i;

//寬度優先搜尋計算出下乙個劃分的最大長度 maxl

memset(vis,false,sizeof(vis));

maxl=s-1;

op=cl=0;

for (i=1;i<=n;i++)

if (b[i]==0)

while (clmaxl)

maxl=maxt[s][k];

for (i=1;i<=used;i++)

if (g[i][k] && !vis[a[i]])

}if (maxl==s-1)

return;

used++;

memcpy(tempa,a,sizeof(a));

memcpy(tempb,b,sizeof(b));

memset(vis,false,sizeof(vis));

g[used]=can[s][maxl];

//擴充套件交錯路。

find(used);

//從大到小列舉下一段的長度。

for (t=maxl;t>=s;t--)

memcpy(a,tempa,sizeof(a));

memcpy(b,tempb,sizeof(b));

}void out()

int main()

NOI2003 逃學的小孩

演算法 最短路 樹的直徑 難度 noip 注意 多年oi一場空,不開long long見祖宗!如果不開long long,應該會被卡到60分!注意 dfs找樹的直徑時,傳的引數 d 也要開long long哦!首先,因為無論如何答案都會包括a到b的dis,所以我們先用2遍dfs找到dis a b 的...

NOI2003 逃學的小孩

傳送門 here 題意 給出一棵樹 帶權 要從乙個節點c先走到距離它近的乙個節點b,再走到a,要求最壞情況下的總路程 即最長 解題思路 乍一看,a,b,c都沒給出,這怎麼求?不妨設距離c較近的點位a。分析發現,無論怎樣,a b是一定要走的。那麼如何能讓樹上任意兩點間距離最大呢?不難發現a,b就是該樹...

NOI2003 逃學的小孩

chris家的 鈴響起了,裡面傳出了chris的老師焦急的聲音 喂,是chris的家長嗎?你們的孩子又沒來上課,不想參加考試了嗎?一聽說要考試,chris的父母就心急如焚,他們決定在盡量短的時間內找到chris。他們告訴chris的老師 根據以往的經驗,chris現在必然躲在朋友shermie或ya...