您的位置:首页 > 其它

Ural 1416 Confidential

2018-01-27 20:49 337 查看
题意:给你N个点,以及M条边,让你计算是否存在最小生成树和次小生成树,如果存在打印出权值,否则打印-1.

代码:#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1005;
int g

;
int dis
;
int path

;
bool used

;
int pre
;
int vis
;
int n,m,q;
void init()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j)g[i][j]=0;
else g[i][j]=inf;
}
}
int prime()
{
memset(path,0,sizeof(path));
memset(vis,0,sizeof(vis));
memset(used,false,sizeof(used));
int i,j;
int ans=0;
for(i=1;i<=n;i++)
{
dis[i]=g[1][i];
pre[i]=1;
}
vis[1]=1;
for(i=1;i<n;i++)
{
int tmp=inf;
int u=-1;
for(j=1;j<=n;j++)
{
if(!vis[j]&&dis[j]<tmp)
{
tmp=dis[j];
u=j;
}
}
if(u==-1)return inf;
vis[u]=1;
used[u][pre[u]]=used[pre[u]][u]=true;
ans+=tmp;
for(j=1;j<=n;j++)
{
if(vis[j]&&u!=j)
{
path[u][j]=path[j][u]=max(path[j][pre[u]],dis[u]);
}
if(!vis[j]&&dis[j]>g[u][j])
{
dis[j]=g[u][j];
pre[j]=u;
}
}
}
return ans;
}
int secondprime(int t)
{
int i,j;
int ans=inf;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i!=j&&!used[i][j])
{
ans=min(ans,t-path[i][j]+g[i][j]);
}
}
}
return ans;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int i;
int x,y,z;
init();
for(i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&z);
g[x][y]=g[y][x]=z;
}
int ans=prime();
if(ans==inf)
{
printf("Cost: -1\n");
}
else printf("Cost: %d\n",ans);
int ans1=secondprime(ans);
if(ans1!=inf)
{
printf("Cost: %d\n",ans1);
}
else
{
printf("Cost: -1\n");
}

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: