54.施工方案第二季(最小生成树)
時間限制: 1 s
?空間限制: 128000 KB
?題目等級 : 黃金 Gold
題解
?查看運行結果
題目描述?Description
c國邊防軍在邊境某處的陣地是由n個地堡組成的。工兵連受命來到陣地要進行兩期施工。
第一期的任務是挖掘暗道讓所有地堡互聯互通。現已勘測設計了m條互不相交的暗道挖掘方案,如果這m條暗道都實施挖掘,肯定能達到互聯互通的目的。事實上,適當選擇其中n-1個方案挖掘,就能實現互聯互通,即從每個地堡出發都能到達其他任何一個地堡(允許經過別的地堡)。
連長精心謀算,在m個設計規劃中選取了挖掘總距離最短且能保證互聯互通的若干個暗道規劃實施了挖掘,完成了第一期的施工任務后又接受了第二期的施工任務,要求選擇一個地堡進行擴建改造,使其能向每個地堡提供彈藥。為了讓彈藥供應更及時、更快捷,從改擴建的地堡到最遠地堡的距離(稱為最遠輸送距離)應當盡量小。
你的任務是先求出第一期施工挖掘的總距離,再求改擴建地堡最遠輸送距離的最小值。
輸入描述?Input Description
其中第一行是n和m,m>=n
下面的m行每行3個數xi、yi、zi,表示xi到yi的距離是zi
??zi<1000000且m個距離互不相等
輸出描述?Output Description
共包含兩行,每行一個整數,
第一行是第一期的挖掘總距離,第二行是最遠輸送距離的最小值。
樣例輸入?Sample Input
4?5
1?2?1
2?3?2
3?4?3
4?1?4
3?1?5
樣例輸出?Sample Output
6
3
數據范圍及提示?Data Size & Hint
【樣例說明】
第一期挖掘1到2、2到3和3到4的3條暗道,第二期選擇3號地堡進行改擴建,最遠輸送距離是3
【數據規模】
60%的數據?n<10且m<20
80%的數據?n<1000且m<2000
100%的數據?n<100000且m<200000
錯誤代碼:(總距離正確)
#include
using namespace std;
#include
#include
#include
#include
#include
#define maxn 100000
#define maxm 200000
struct Edge{
?????? int u,v,next;
?????? long long w;
};
Edge edge[2*maxm];
long long tot=0;
int visit[maxn]={0},head[maxn],man[maxn];
int maxdis[maxn],n,m;
void input();
void prim();
int main()
{
?????? input();
?????? prim();
?????? printf("%lld\n",tot);
?????? for(int i=2;i<=n;++i)
?????? {
????????????? if(maxdis[i]!=0&&maxdis[i]
????????????? ?maxdis[1]=maxdis[i];
?????? }
?????? printf("%d\n",maxdis[1]);
?????? return 0;
}
void input()
{
?????? memset(maxdis,0,sizeof(maxdis));
?????? int a,b;
?????? long long c;
?????? head[1]=0;
?????? scanf("%d%d",&n,&m);
?????? for(int i=1;i<=m;++i)
?????? {
????????????? scanf("%d%d%d",&a,&b,&c);
????????????? edge[i].u=a;edge[i].v=b;
????????????? edge[i].w=c;
????????????? edge[i].next=head[a];
????????????? head[a]=i;
????????????? if(c>maxdis[a])
????????????? maxdis[a]=c;
????????????? edge[i+m].v=a;edge[i+m].u=b;
????????????? edge[i+m].w=c;
????????????? edge[i+m].next=head[b];
????????????? head[b]=i+m;
????????????? if(c>maxdis[b])
????????????? maxdis[b]=c;
?????? }
}
void prim()
{
?????? memset(man,99,sizeof(man));
?????? man[1]=0;
?????? int k=1;
?????? visit[k]=1;
?????? tot+=man[k];
?????? for(int i=2;i<=n-1;++i)
?????? {
????????????? int minxx=999999;
????????????? for(int j=1;j<=n;++j)
????????????? {
???????????????????? if(!visit[j]&&man[j]
???????????????????? {
??????????????????????????? minxx=man[j];
??????????????????????????? k=j;
???????????????????? }
????????????? }
????????????? visit[k]=1;
????????????? tot+=man[k];
????????????? for(int j=head[k];j!=0;j=edge[j].next)
????????????? {
???????????????????? if(!visit[edge[j].v]&&edge[j].w
???????????????????? {
??????????????????????????? man[edge[i].v]=edge[j].w;
???????????????????????????
???????????????????? }
????????????????????
????????????? }
?????? }
}
正確:
#include
#include
#include
#include
#include
#define maxn 100005
#define INF 0x7fffffff
?
long long cnt,head[maxn],fa[maxn],vis[maxn],down[maxn][2],up[maxn],dis[maxn];
int n,m;
struct node
?? {
?? ? ?int to;
?? ? ?int next;
?? ? ?int edge;
?? }e[maxn<<2];
?
struct ss
?? {
?? ? int x,y,z;
?? }a[maxn];
?
using namespace std;
?
void insert(int u,int v,int edge)
??? {
???? e[++cnt].to=v;
???? e[cnt].edge=edge;
???? e[cnt].next=head[u];
???? head[u]=cnt;
?????? }
?
int find(int x)
?? {
?? ? ?if (fa[x]==x) return x;
?? ? ?fa[x]=find(fa[x]);
?? ? ?return fa[x];
?? }
??
bool cmp(ss a,ss b)??
??? {
??? ?????? return a.z
?????? }
??????
void dfs1(int rt)
?? {
?? ? ?vis[rt]=1;
?? ? ?for (int i=head[rt];i;i=e[i].next)
?? ? ???{
?? ? ?????if (!vis[e[i].to]) dfs1(e[i].to);
?? ? ?????????else continue;
?? ? ?????if (down[e[i].to][0]+e[i].edge>down[rt][0])
????????????? ??? {
????????????? ????? down[rt][1]=down[rt][0];
???????????????????? ? down[rt][0]=down[e[i].to][0]+e[i].edge;?
????????????? ??? }???
????????????? ??? else if (down[e[i].to][0]+e[i].edge>down[rt][1])
????????????? ???????? down[rt][1]=down[e[i].to][0]+e[i].edge;
?????? ?? }??????
??? }
??????
void dfs2(int rt,int fat,int val)
??? {
????? vis[rt]=1;???
????? long long tmp=0;??????
????? if (rt==1) up[rt]=0;
?????? ???? else
????????????? ?? {
????????????? ?? ? ?up[rt]=up[fat]+val;
????????????? ???? if (down[fat][0]==down[rt][0]+val) tmp=down[fat][1]+val;
???????????????????? ??? else tmp=down[fat][0]+val;
???????????????????? ?up[rt]=max(up[rt],tmp);????????????
????????????? ?? }
?????? ? dis[rt]=max(up[rt],down[rt][0]);
?????? ? for (int i=head[rt];i;i=e[i].next)
?????? ????? if (!vis[e[i].to]) dfs2(e[i].to,rt,e[i].edge); ?? ?
?????? }????
??????
int main()
?? {
?? ? ?scanf("%d%d",&n,&m);
?? ? ?long long ans2=INF;
?? ? ?for (int i=1;i<=m;i++)
?? ? ???scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
?? ? ?sort(a+1,a+m+1,cmp);
?? ? ?for (int i=1;i<=n;i++) fa[i]=i;
?? ? ?int k=0,ans=0;
?? ? ?for (int i=1;i<=m;i++)
?? ? ?????{
?? ? ????????? int fa1=find(a[i].x),fa2=find(a[i].y);
?? ? ????????? if (fa1==fa2) continue;
?? ? ????????? fa[fa2]=fa1;
?? ? ????????? insert(a[i].x,a[i].y,a[i].z);
?? ? ????????? insert(a[i].y,a[i].x,a[i].z);
?? ? ????????? k++;
?? ? ????????? ans+=a[i].z;
?? ? ????????? if (k==n-1) break;
???????????????????? }
???? printf("%lld\n",ans);
?????? ?memset(vis,0,sizeof(vis));
?????? ?dfs1(1);
?????? ?memset(vis,0,sizeof(vis));
?????? ?dfs2(1,0,0);
?????? ?for (int i=1;i<=n;i++)
?????? ??? ans2=min(ans2,dis[i]);
?????? ?printf("%lld",ans2);???? ???? ??????????????????
?????? ?return 0;
?????? ? }
轉載于:https://www.cnblogs.com/c1299401227/p/5370766.html
總結
以上是生活随笔為你收集整理的54.施工方案第二季(最小生成树)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到很多鱼是胎梦吗
- 下一篇: 孕妇梦到聚餐是什么意思