版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/87101970
A. UVALive 6437 Power Plant
题目
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=205;
template<typename T>inline void read(T &x)
{
x=0;
T f=1,ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
struct rec
{
int x,y,z;
}edge[maxn*maxn];
int fa[maxn];
inline int get(int x)
{
if (fa[x]==x) return x;
return fa[x]=get(fa[x]);
}
inline bool cmp(rec a,rec b)
{
return a.z<b.z;
}
int main()
{
int t;read(t);
for (int cnt=1;cnt<=t;++cnt)
{
int n,m,k,f,ans=0;
read(n);read(m);read(k);
for (int i=1;i<=n;++i)
fa[i]=i;
read(f);
for (int i=2;i<=k;++i)
{
int x;read(x);
fa[x]=f;
}
for (int i=1;i<=m;++i)
{
read(edge[i].x);
read(edge[i].y);
read(edge[i].z);
}
sort(edge+1,edge+m+1,cmp);
for (int i=1;i<=m;++i)
{
int x=edge[i].x;
int y=edge[i].y;
if (get(x)==get(y)) continue;
fa[fa[x]]=fa[y];
ans+=edge[i].z;
}
printf("Case #%d: %d\n",cnt,ans);
}
return 0;
}
B. UVA 10369 Arctic Network
题目
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=5005;
template<typename T>inline void read(T &x)
{
x=0;
T f=1,ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
struct rec
{
int fr,to;
double z;
}edge[maxn*maxn];
int fa[maxn],dx[maxn],dy[maxn];
inline int get(int x)
{
return fa[x]==x?x:fa[x]=get(fa[x]);
}
inline void combine(int x,int y)
{
int xx=get(x),yy=get(y);
if (xx!=yy) fa[xx]=yy;
}
inline bool cmp(rec a,rec b)
{
return a.z<b.z;
}
int main()
{
int t;read(t);
while (t--)
{
int m,n,len=0,tot=0;
double ans=0.00;
read(m);read(n);
for (int i=1;i<=n;++i)
{
fa[i]=i;
read(dx[i]);read(dy[i]);
}
for (int i=1;i<n;++i)
for (int j=i+1;j<=n;++j)
edge[++len].fr=i,edge[len].to=j,
edge[len].z=sqrt(double((dx[i]-dx[j])*(dx[i]-dx[j]))+double((dy[i]-dy[j])*(dy[i]-dy[j])));
sort(edge+1,edge+len+1,cmp);
for (int i=1;i<=len;++i)
{
if (get(fa[edge[i].fr])!=get(fa[edge[i].to]))
{
combine(edge[i].fr,edge[i].to);
++tot;
ans=edge[i].z;
}
if (tot==n-m) break;
}
printf("%.2lf\n",ans);
}
return 0;
}
C. BZOJ 1232: [Usaco2008Nov]安慰奶牛cheer
题目
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
template<typename T>inline void read(T &x)
{
x=0;
T f=1,ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
struct rec
{
int x,y,z;
}edge[maxn<<1];
int fa[maxn],c[maxn],ans=0x3f3f3f3f,tot;
inline int get(int x)
{
if (x==fa[x]) return x;
return fa[x]=get(fa[x]);
}
inline bool cmp(rec a,rec b)
{
return a.z<b.z;
}
int main()
{
int n,p;
read(n);read(p);
for (int i=1;i<=n;++i)
{
read(c[i]);
ans=min(ans,c[i]);
fa[i]=i;
}
for (int i=1;i<=p;++i)
{
int x,y,z;
read(x);read(y);read(z);
z=(z<<1)+c[x]+c[y];
edge[i].x=x,edge[i].y=y,edge[i].z=z;
}
sort(edge+1,edge+p+1,cmp);
for (int i=1;i<=p;++i)
{
int x=get(edge[i].x);
int y=get(edge[i].y);
if (x!=y)
{
fa[x]=y;
++tot;
ans+=edge[i].z;
}
if (tot==n-1) break;
}
printf("%d\n",ans);
return 0;
}
D. UVA1151 Buy or Build
题目
代码
#include<algorithm>
#include<bitset>
#include<cctype>
#include<cerrno>
#include<clocale>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<utility>
#include<vector>
#include<cwchar>
#include<cwctype>
using namespace std;
const int maxn=1e3+5;
const int maxm=5e5+5e2;
template<typename T>inline void read(T &x)
{
x=0;
T f=1,ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
struct Node
{
int x,y;
}node[maxn];
struct rec
{
int x,y,z;
bool operator < (const rec &a) const
{
return z<a.z;
}
}edge[maxm];
int fa[maxn],cost[10];
int n,q,num;
vector<int>g[10];
inline int get(int x)
{
if (fa[x]==x) return x;
return fa[x]=get(fa[x]);
}
inline int combine(int x,int y)
{
int xx=get(x),yy=get(y);
if (xx==yy) return false;
fa[xx]=yy;
return true;
}
int Kruskal()
{
int ans=0,cnt=0;
for (int i=0;i<num;++i)
{
if (combine(edge[i].x,edge[i].y))
{
ans+=edge[i].z;
++cnt;
}
if (cnt==n-1) break;
}
return ans;
}
int main()
{
// int t;read(t);
// while (t--)
// {
read(n);read(q);
for (int i=0;i<q;++i)
{
g[i].clear();int number;
read(number);read(cost[i]);
for (int j=0;j<number;++j)
{
int x;read(x);
g[i].push_back(x);
}
}
for (int i=1;i<=n;++i)
{
read(node[i].x);
read(node[i].y);
}
for (int i=1;i<=n;++i)
for (int j=i+1;j<=n;++j)
edge[num].x=i,edge[num].y=j,
edge[num++].z=(node[i].x-node[j].x)*(node[i].x-node[j].x)+(node[i].y-node[j].y)*(node[i].y-node[j].y);
sort(edge,edge+num);
for (int i=0;i<=n;++i)
fa[i]=i;
int ans=Kruskal();
for (int i=0;i<(1<<q);++i)
{
for (int k=0;k<=n;++k)
fa[k]=k;
int all=0;
for (int j=0;j<q;++j)
{
if (!((i>>j)&1)) continue;//if (1!=(i>>j))
all+=cost[j];
for (int k=1;k<g[j].size();++k)
combine(g[j][k],g[j][0]);
}
ans=min(ans,all+Kruskal());
}
printf("%d\n",ans);
// if (t) puts("");
// }
return 0;
}
E. POJ 3522 Slim Span
题目
题意
给出一个图,若图连通,则求最大边与最小边差值最小的生成树,输出最小差值。否则输出-1。
题解
其实就是求边权差值最小的生成树。
1.首先我们看一下数据范围,
,很小,所以我们就可以直接枚举最小边。
2.接着跑最小生成树,就是瓶颈生成树,因为最小生成树有一个很重要的性质:在构造生成树时有可能选择不同的边,但最小生成树的权是唯一的!所以在用kruskal算法时第一次加入的必然是最小生成树的最小边权值,最小边确定后,==最小生成树的最大边的权值是所以生成树中最小的,==即为瓶颈生成树。
3.然后更新答案即可。
代码
#include<algorithm>
#include<bitset>
#include<cctype>
#include<cerrno>
#include<clocale>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<utility>
#include<vector>
#include<cwchar>
#include<cwctype>
using namespace std;
const int maxn=2e5+10;
char buf[1<<15],*fs,*ft;
inline char getc(){return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++;}
inline int read()
{
int num=0,f=1;char ch=getchar();
while (!isdigit(ch)) { if(ch=='-') f=-1; ch=getchar(); }
while (isdigit(ch)) num=(num<<3)+(num<<1)+(ch^48), ch=getchar();
return num*f;
}
struct rec
{
int x,y,z;
}edge[maxn];
int fa[maxn],ans;
inline bool operator < (rec a,rec b)
{
return a.z<b.z;
}
inline int get(int x)
{
if (x==fa[x]) return x;
return fa[x]=get(fa[x]);
}
int main()
{
while (1)
{
int n=read(),m=read(),i=0;
if (!n && !m) break;
if (n==1)
{
puts("0");
exit(0);
}
for (i=1;i<=m;++i)
edge[i].x=read(),edge[i].y=read(),edge[i].z=read();
sort(edge+1,edge+m+1);
ans=edge[m].z;//差值初始化
for (int k=1;k<=m;++k)//以k为最小边进行枚举
{
int sum=0;//最小生成树的边数
for (i=1;i<=n;++i)//生成树初始化
fa[i]=i;
for (i=k;i<=m;++i)//求最小生成树
{
int x=get(edge[i].x);
int y=get(edge[i].y);
if (x==y) continue;
fa[x]=y;
++sum;
if (sum==n-1)//已构成一个最小生成树(从定义出发)
{
ans=min(ans,edge[i].z-edge[k].z);//最大边减去最小边
break;
}
}
if (i==m+1) break;
}
if (ans==edge[m].z)//ans未经过改变,说明此图未连通
puts("-1");
else
printf("%d\n",ans);
}
return 0;
}
F. UVA10816 Travel in Desert
题目
题解
首先,这是一道 生成树最短路 的题。
代码
#include<algorithm>
#include<bitset>
#include<cctype>
#include<cerrno>
#include<clocale>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<utility>
#include<vector>
#include<cwchar>
#include<cwctype>
using namespace std;
const int maxn=1e4+5;
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
struct MST
{
int fr,to;
double tem,len;
friend bool operator < (const MST &a,const MST &b)
{
return a.tem<b.tem;
}
}tree[maxn<<1];
int ver[maxn<<1],Next[maxn<<1],head[maxn],len,num;
double edge[maxn<<1];
inline void add(int x,int y,double z)
{
ver[++len]=y,edge[len]=z,Next[len]=head[x],head[x]=len;
}
inline void insert(int x,int y,double tem,double dis)
{
tree[++num].fr=x,tree[num].to=y,tree[num].len=dis,tree[num].tem=tem;
}
int fa[maxn],n,m,s,t;
inline int get(int x)
{
return fa[x]==x?x:fa[x]=get(fa[x]);
}
struct HeapNode
{
int u;//点
double d;//距离
friend bool operator < (const HeapNode &a,const HeapNode &b)
{
return a.d>b.d;
}
};
priority_queue<HeapNode> q;
vector<int> path;
double maxtem,dist[maxn];
bool vis[maxn];
inline void heap_dijkstra()
{
for (register int i=1;i<=n;++i)
dist[i]=0x3f3f3f3f,vis[i]=0,fa[i]=0;
dist[s]=0;
q.push((HeapNode){s,dist[s]});
while (!q.empty())
{
int x=q.top().u;
q.pop();
if (vis[x]) continue;
vis[x]=1;
for (int i=head[x];i;i=Next[i])
{
int y=ver[i];
double z=edge[i];
if (dist[y]>dist[x]+z)
{
dist[y]=dist[x]+z;
fa[y]=x;//再跑最短路的同时,用并查集确定x与y之间的关系,即x是y的父亲
q.push((HeapNode){y,dist[y]});
}
}
}
register int x=t;
path.clear();
while (x!=s)//从终点出发,一直在树上遍历到起点,就刚好把路径加入到path[]中
{
path.push_back(x);
x=fa[x];
}
path.push_back(s);
for (register int i=path.size()-1;i>=1;--i)
printf("%d ",path[i]);
printf("%d\n",path[0]);
}
int main()
{
while (~scanf("%d%d",&n,&m))
{
num=len=0;maxtem=0;
memset(head,0,sizeof(head));
memset(fa,0,sizeof(fa));
read(s);read(t);
register double te,w;
for (register int i=1,fr,to;i<=m;++i)
{
read(fr);read(to);
scanf("%lf%lf",&te,&w);
insert(fr,to,te,w);
}
for (register int i=1;i<=n;++i)
fa[i]=i;
sort(tree+1,tree+m+1);
for (register int i=1;i<=m;++i)
{
register int x=get(tree[i].fr),y=get(tree[i].to);
if (x!=y)
{
fa[x]=y;
maxtem=max(maxtem,tree[i].tem);
if (get(s)==get(t)) break;
}
}
for (int i=1;i<=m;++i)
{
if (tree[i].tem>maxtem) break;;
add(tree[i].fr,tree[i].to,tree[i].len);
add(tree[i].to,tree[i].fr,tree[i].len);
}
heap_dijkstra();
printf("%.1f %.1f\n",dist[t],maxtem);
}
return 0;
}
G. POJ 1639 Picnic Planning
题目
代码
暂时还没有了噻!!QWQ