22.网络提速(最短路)
時間限制: 1 s
?空間限制: 128000 KB
?題目等級 : 黃金 Gold
題解
?查看運行結果
題目描述?Description
某學校的校園網由n(1<=n<=50)臺計算機組成,計算機之間由網線相連,如圖5。其中頂點代表計算機,邊代表網線。正如你所見,不同網線的傳輸能力不盡相同,例如計算機1與計算機2之間傳輸信息需要34秒,而計算機2與計算機3之間的傳輸信息只要10秒。計算機1與計算機5之間傳輸信息需要44秒,途徑為機1到機3到機5。
現學校購買了m(1<=m<=10)臺加速設備,每臺設備可作用于一條網線,使網線上傳輸信息用時減半。多臺設備可用于同一條網線,其效果疊加,即用兩臺設備,用時為原來的1/4,用三臺設備,用時為原來的1/8。如何合理使用這些設備,使計算機1到計算機n傳輸用時最少,這個問題急需解決。校方請你編程解決這個問題。例如圖5,若m=2,則將兩臺設備分別用于1-3,3-5的線路,傳輸用時可減少為22秒,這是最佳解。
輸入描述?Input Description
第一行先輸入n,m。以下n行,每行有n個實數。第i行第j列的數為計算機i與計算機j之間網線的傳輸用時,0表示它們之間沒有網線連接。注意輸入數據中,從計算機1到計算機n至少有一條網路。
?
輸出描述?Output Description
輸出計算機1與計算機n之間傳輸信息的最短時間。(保留兩位小數)
樣例輸入?Sample Input
5?2
0?34?24?0?0
34?0?10?12?0
24?10?0?16?20
0?12?16?0?30
0?0?20?30?0
樣例輸出?Sample Output
22.00
數據范圍及提示?Data Size & Hint
分類標簽?Tags?點此展開?
思路:先找出1—n的最短路,再從最短路上,從邊的權值的大到小順序除二知道m==0為止
?
代碼:
#include
using namespace std;
const int maxn=51;
#include
#include
#include
int n,m,p[maxn][maxn],dist[maxn],pre[maxn],visit[maxn]={0},t=0;
double sum=0;
struct Edge{
?????? int from,to;
?????? double weigh;//因為最后結果保存2位小數,所以權值也要是浮點數才行
};
Edge edge[maxn*maxn];//存最短路徑的邊
void input();
void dijkstra();
int cmp(const Edge &a,const Edge &b)
{
?????? return a.weigh>b.weigh;
}
void stim()
{
?????? while(pre[n]!=0)//把最短路徑放到結構體中
?????? {
????????????? edge[++t].from=pre[n];
????????????? edge[t].to=n;
????????????? edge[t].weigh=p[pre[n]][n];
????????????? n=pre[n];
????????????????????
?????? }
?????? sort(edge+1,edge+t+1,cmp);//巴結構體的邊權有大到小排序
?????? int edgel;
? while(m)
? {
???? edgel=1;//比較指針
?????? ?while(m)
?????? ?{
????????????? while(edge[edgel].weigh>edge[edgel+1].weigh)//把大數一次性除得比第二個數小
????????????? {
???????????????????? m--;
???????????????????? edge[edgel].weigh/=2;
???????????????????? if(m==0)return;
????????????????????
????????????? }
????????????? edgel++;//比較2與3
????????????? if(edgel==t) //比到最后一個時,再重新排序,由大到小,分別/2
???????????????????? break;
?????????????
?????????????
?????? ?}
?????? sort(edge+1,edge+t+1,cmp);
? }
?
}
int main()
{
?????? input();
?????? dijkstra();
?????? stim();
?????? for(int i=1;i<=t;++i)
?????? sum+=edge[i].weigh;
?????? printf("%.2lf",sum);
?????? return 0;
}
void dijkstra()
{
??? visit[1]=1;
?????? pre[1]=0;//把1的前驅設為0
?????? dist[1]=0;//注意
?????? for(int i=2;i<=n;++i)
??? ?????? if(dist[i]<99999)
????????????? ?pre[i]=1;?????? //把前驅是1的先設上,因為下面算法,不會給他設
?????? for(int i=1;i<=n;++i)
?????? {
????????????? int min=99999,k=0;
????????????? for(int j=1;j<=n;++j)
????????????? {
???????????????????? if(dist[j]
????????????? ??? {
????????????? ??? ?????? k=j;
????????????? ??? ?????? min=dist[j];
???????????????????? }
????????????? }
????????????? if(k==0) break;
????????????? visit[k]=1;
????????????? for(int j=1;j<=n;++j)
????????????? {
???????????????????? if(dist[j]>dist[k]+p[k][j])
???????????????????? {
??????????????????????????? dist[j]=dist[k]+p[k][j];
??????????????????????????? pre[j]=k;//記錄前驅
???????????????????? }
????????????? }
?????? }
??????
}
void input()
{
?????? scanf("%d%d",&n,&m);
?????? for(int i=1;i<=n;++i)
?????? ? for(int j=1;j<=n;++j)
?????? ? {
?????? ? ??? scanf("%d",&p[i][j]);
?????? ? ??? if(p[i][j]==0)
?????? ? ??? p[i][j]=99999;
?????? ? ??? if(i==1)
?????? ? ??? dist[j]=p[i][j];
?????? ? }
}
轉載于:https://www.cnblogs.com/csgc0131123/p/5290510.html
總結
以上是生活随笔為你收集整理的22.网络提速(最短路)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Eclipse中打开Hadoop工程
- 下一篇: 【UNIX网络编程(二)】基本TCP套接