迪傑斯特拉派初賽賽題
最強大腦中的收官蜂巢迷宮**級挑戰,相信大家都嘆為觀止!最強大腦收官戰打響後,收視率節節攀公升,就連蟻后也不時出題難為一下她的子民們。在動物世界中,稱得上活地圖的,除了蜜蜂,螞蟻當仁不讓。在複雜多變的蟻巢中, 螞蟻總是能以最快、最高效的方式遊歷在各個儲藏間(儲存食物)。今天,她看完最新一期節目,又發布了一項新任務:小蟻同學,我需要玉公尺庫的玉公尺,再要配點水果,去幫我找來吧。小蟻正準備出發,蟻后又說:哎呀,回來,我還沒說完呢,還有若干要求如下:
1.小蟻同學,你需要盡可能以最少的花費拿到食物(附件圖中路線上的數值表示每兩個儲物間的花費);
2.小蟻同學,你最多只能經過9個儲藏間拿到食物(包含起止兩個節點,多次通過同一節點按重複次數計算);
3.小蟻同學,你必須經過玉公尺間,水果間(附件圖中標綠色節點);
5.最後,千萬別忘了,還有兩段路是必須經過的,那裡有我準備的神秘禮物等著你呢(附件圖中標綠色路段)。
這下小蟻犯難了,這和它們平時找食物的集體活動規則不一樣嘛,看來這次需要單獨行動了。要怎麼選路呢?小蟻經過一番苦思冥想,稿紙堆了一摞,啊,終於找到了!親愛的同學們,你們能否也設計一種通用的路徑搜尋演算法,來應對各種搜尋限制條件,找到一條最優路徑,順利完成蟻后布置的任務呢?
注:1、蟻巢,有若干個儲藏間,儲藏間之間有諸多路可以到達;
2、節點本身通行無花費;
3、該圖為無向圖,可以正反兩方向通行,兩方向都會計費,並且花費相同;
4、起止節點分別為附件圖中s點和e點。
5、最優路徑:即滿足限制條件的路徑。
附在**下面了,我的解決方案是對整個圖進行乙個限制路徑的dij,用乙個set來判斷特殊點的個數,之後對特殊情況進行判斷一下就行了。這個解法主要的優點是通用,的確犧牲了一下次優解的情況,只有70分,沒拿到區域優勝有點可惜。順便幫助隊友拿到數模校賽一等獎(題目一樣)
#include
#define inf 0x3f3f3f3f
using
namespace
std;
const
int maxnum = 100;
const
int maxint = 999999;
int dist[maxnum]; //initialize with maxint
int prev[maxnum];
int c[maxnum][maxnum]; //initialize with maxint
int n, line; // 圖的結點數和路徑數
set sp_nodes;
bool sp_edge[maxnum][maxnum];
// n -- n nodes
// v -- the source node
// dist -- the distance from the ith node to the source node
// prev -- the previous node of the ith node
// c -- every two nodes' distance
inline
long
long fac(int n)
return res;
}void dijkstra_modify(int n, int v)
dist[v] = 0;
s[v] = 1;
for(int i=1; iint tmp = maxint;
int u = v;
for(int j=0; jif((!s[j]) && dist[j]// let the special nodes and the current point's edge minimum
// but if there are mutiple of special node ?
}s[u] = 1;
// refresh extend
// no need to change
for(int j=0; jif((!s[j]) && c[u][j]int newdist = dist[u] + c[u][j];
if(newdist < dist[j])}}
}void print(int x,int s)
q.push(s);
while(q.empty()==0)
cout
<<"\n";
}int main()
}for(int i=0; icin>>t1>>t2>>t3;
c[t1][t2] = c[t2][t1] = t3;}//
cin>>st_node>>tm_node;
for(int i=0; i<2; i++)
for(int i=0; i<2; i++)
//edge that unreachable
cin>>t1>>t2;
c[t1][t2] = c[t2][t1] = maxint;
//begin
vector
path,path_p;
vector
sp_nodes_p;
int cnt=0;
int ans=maxint;
int cnt_nodes=0;
for(set
::iterator sit = sp_nodes.begin(); sit!=sp_nodes.end(); sit++)
int times=fac(sp_nodes.size());
for(int i=0; i//generate the permutation
next_permutation(sp_nodes_p.begin(),sp_nodes_p.end());
path_p.clear();
vector
::iterator it = sp_nodes_p.begin();
dijkstra_modify(n,st_node);
cnt += dist[*it];
path.push_back(*it);
//cout<<"st: "memcpy(sp_edge_p,sp_edge,sizeof(sp_edge_p));
bool flag = true;
while(1)
if(sp_edge_p[tmp][*it])
else
}if(!flag)
dijkstra_modify(n,tmp);
cnt += dist[*it];
//refresh the temp
//cout<<"short : "<"<<*it<<" : ";
//print(*it,tmp);
stack
q;int tmp2=*it;
while(tmp2!=tmp)
while(q.empty()==0)
//cout<}
}if(!flag)
int e=sp_nodes_p[sp_nodes_p.size()-1];
dijkstra_modify(n,e);
cnt+=dist[tm_node];
//cout<<"path :";
int judge=st_node;
//cout cnt)
cnt_nodes=path.size();
}cnt=0;
}cout
<<"distance :"
cout
<<"path :"
<"->";
for(int i=0; iif(judge == path[i]) continue;
cout
<"->";
judge=path[i];
}cout
6)
ChinaUnix第一屆「C語言」開發大賽的第三題
3.從標準輸入中讀入 n 1行以換行符結束且長度不超過 2048 的字串,並在輸入結束後輸出其中最長 10行的輸入序號 長度和內容。當有多行長度相等的最長行時,輸出最先輸入的行的資訊。個人寫的 如下 include include include define len sizeof struct l...
ChinaUnix第一屆「C語言」開發大賽的第二題
第二題 給定 n 3 n 50000 個閉區間 ai,bi 1 i n,ai,bi 均為非負整數 將這些區間合併為不相交的閉區間。輸入檔案 的第一行包含乙個整數n,為區間的數目。以下有n行,每行各包括兩個空格分隔的整數ai 和bi,表示乙個區間 ai,bi 0 ai bi 1000000 計算結果寫...
ChinaUnix第一屆「C語言」開發大賽的第一題
給定乙個整數n,生成乙個n n的矩陣,矩陣中元素取值為1至 n2,1在左上角,其餘各數按順時針方向旋轉前進,依次遞增放置。例如,當 n 4時,矩陣中的內 容如下 12 341213145 1116156 10987 個人寫的 如下 include include 矩陣賦值 思想是 就是一圈一圈的賦值...