训练总结 8.7
来源:互联网 发布:mysql数据库管理 编辑:程序博客网 时间:2024/05/29 11:15
今天做的题都是图论的题,两道floyd算法题,两道prim算法题,还有一道Dijkstra算法题。思路和写法都是相似的,题也比较简单。
1、Frogger
prim算法求最小生成树,找最小生成树的最大权值。
2、Stockbroker Grapevine
floyd算法,该题中图不一定是连通的。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define q 0xfffffff
int n,m,sum,s,p;
int mp[101][101];
int main()
{
while(scanf("%d",&n)&&n)
{
//memset(mp,q,sizeof(mp));//不能用memset函数赋极大值
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
mp[i][j]=q;
for(int i=1;i<=n;i++)
{
scanf("%d",&m);
for(int j=1;j<=m;j++)
{
int x1,y1;
cin>>x1>>y1;
mp[i][x1]=y1;
}
}
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i!=k&&i!=j&&k!=j&&mp[k][j]<q&&mp[i][k]<q)
mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
}
}
}
sum=q;
for(int i=1;i<=n;i++)
{
s=0;
for(int j=1;j<=n;j++)
{
if(i==j)continue;
s=max(s,mp[i][j]);
}//同一起点值最大的为信息传播给所有人的时间
if(sum>s)
{
sum=s;
p=i;
}
}
if(sum==q)
printf("disjoint\n");
else
printf("%d %d\n",p,sum);
}
return 0;
}
3、昂贵的聘礼
这道题比较麻烦,在初始化的时候,将已知条件转化为符合图论算法的条件。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int m,n;
int p[101],l[101],x[101];
int t,v;
bool vis[101];
int money[101][101];//用j商品再加上金币money[i][j]即可换购i商品
int dis[101];
bool change[101];
int dijkstra()
{
memset(vis,0,sizeof(vis));
//memset(dis,0xfffffff,sizeof(dis));
for(int i=1;i<=n;i++)
dis[i]=0xfffffff;
dis[1]=0;
for(int i=1;i<=n;i++)
{
int pos=-1;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&change[j]&&(pos==-1||dis[j]<dis[pos]))
pos=j;
}
vis[pos]=true;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&change[j]&&dis[j]>dis[pos]+money[pos][j])
dis[j]=dis[pos]+money[pos][j];
}
}
int mmin=0xfffffff;
for(int i=1;i<=n;i++)
{
dis[i]+=p[i];
mmin=min(mmin,dis[i]);
}
return mmin;
}
/*int dijkstra()
{
memset(vis,false,sizeof vis);
for(int i=1;i<=n;i++)
dis[i]=0xfffffff;
dis[1]=0;
for(int i=1;i<=n;i++)
{
int pos=-1;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&change[j]&&(pos==-1||dis[j]<dis[pos]))
pos=j;
}
vis[pos]=true;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&change[j]&&dis[j]>dis[pos]+money[pos][j])
{
dis[j]=dis[pos]+money[pos][j];
}
}
}
int mine=0xfffffff;
for(int i=1;i<=n;i++)//dis[i]存的是从第1号商品到第i-1号商品的所有优惠价格 这时还应该加上第i件商品的原价 因为他是第一件不能优惠
{
dis[i]+=p[i];
mine=min(mine,dis[i]);
}
return mine;
}*/
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
money[i][j]=0;
else
money[i][j]=0xfffffff;
}
}
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&p[i],&l[i],&x[i]);
while(x[i]--)
{
scanf("%d%d",&t,&v);
money[i][t]=min(money[i][t],v);
}
}
int Min=0xfffffff;
for(int i=0;i<=m;i++)
{
memset(change,0,sizeof(change));
for(int j=1;j<=n;j++)
{
if(l[j]>=l[1]-m+i&&l[j]<=l[1]+i)
change[j]=true;
}
Min=min(Min,dijkstra());
}
printf("%d\n",Min);
}
return 0;
}
4、Truck History
很简单的prim算法
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
using namespace std;
int n,k;
char ch[2001][11];
int mp[2001][2001];
bool vis[2001];
int dis[2001];
int prim()
{
/*int sum=0;
int next,Min;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
dis[i]=mp[1][i];
vis[1]=1;
for(int i=2;i<=n;i++)
{
Min=0xfffffff;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&Min>dis[j])
{
Min=dis[j];
next=j;
}
}
sum+=Min;
vis[next]=1;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&dis[j]>mp[next][j])
dis[j]=mp[next][j];
}
}
return sum;*/
int ans=0;
for(int i=0;i<=n;i++)
dis[i]=0xfffffff;//一开始没有给dis[0]赋值,找了好长时间的错
memset(vis,0,sizeof(vis));
dis[1]=0;
while(1)
{
//cout<<ans<<endl;
k=0;
for(int j=1;j<=n;j++)
if(!vis[j]&&dis[j]<dis[k])
k=j;
if(!k)break;
vis[k]=1;
ans+=dis[k];
for(int j=1;j<=n;j++)
{
if(dis[j]>mp[k][j])
dis[j]=mp[k][j];
}
}
return ans;
/*int t,pos;
double Min,Max=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
low[i]=mp[1][i];
vis[1]=1;
pos=1;
t=0;
for(int i=1;i<n;i++)
{
Min=0xfffffff;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&low[j]<Min)
{
Min=low[j];
pos=j;
}
}
if(Min>Max)
Max=Min;
if(pos==2)
return Max;
vis[pos]=1;
for(int j=1;j<=n;j++)
if(!vis[j]&&low[j]>mp[pos][j])
low[j]=mp[pos][j];
}*/
}
int main()
{
while(scanf("%d",&n)&&n)
{
//memset(mp,0,sizeof(mp));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j)mp[i][j]=0;
else
mp[i][j]=0xfffffff;
}
for(int i=1;i<=n;i++)
{
scanf("%s",ch[i]);
}
for(int i=1;i<n;i++)
{
for(int j=i+1;j<=n;j++)
{
int s=0;
for(int k=0;k<7;k++)
if(ch[i][k]!=ch[j][k])
s++;
mp[j][i]=mp[i][j]=s;
}
}
prim();
printf("The highest possible quality is 1/%d.\n",prim());
}
return 0;
}
5、Arbitrage
不同货币之间的转化,问是否存在路径使钱增加。floyd算法的变型,化加为乘,求最大值。
#include<iostream>
#include<algorithm>
#include<map>
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;
int n,m;
double mp[31][31];
map<string,int>ma;
int main()
{
int cas=1;
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=1;i<=n;i++)
{
string s;
cin>>s;
ma[s]=i;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
mp[i][j]=1.0;
else
mp[i][j]=0;
}
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
char a[101],b[101];
double c;
scanf("%s%lf%s",a,&c,b);
mp[ma[a]][ma[b]]=c;
}
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
mp[i][j]=max(mp[i][j],mp[i][k]*mp[k][j]);
}
}
}
bool falg=false;
for(int i=1;i<=n;i++)
{
if(mp[i][i]>1.0)
{
falg=true;
break;
}
}
if(falg)
printf("Case %d: Yes\n",cas);
else
printf("Case %d: No\n",cas);
cas++;
}
return 0;
}
- 训练总结 8.7
- 训练总结8.7
- 训练总结
- 训练总结
- 训练总结
- 训练总结
- 训练总结
- 训练总结
- 拓展训练总结
- 专业技能训练总结
- 科研技能训练总结
- 第一轮训练总结
- 【SCOI2012】训练总结
- 拓展训练总结
- 20120810训练赛总结
- 20120811训练赛总结
- 【总结】121014DP训练
- 训练指南---总结
- C#@的功能总结
- windows可视化编程(四)
- java获取windows系统的CPU等信息
- 题目77——开灯问题
- java Set接口
- 训练总结 8.7
- 华为p8青春版(ALE-UL00)刷机教程
- 我想减肥不用做力量练习吗?
- html javascript全局函数和Number对象
- BeanFactory
- git diff
- hadoop2.0 HA的主备自动切换
- [LeetCode] 521. Longest Uncommon Subsequence I
- 洛谷3374 树状数组1&2