图中共有N个点的完全图,每条边都有权值,每个点也有权值。要求选出M个点和M-1条边,构成一棵树,使得:
即所有边的权值与所有点的权值之和的比率最小。
给定N和M,以及N个点的权值,和所有的边权,要求M个点的最小比率生成树。
N和M(2<=N<=15,2<=M<=N)
15的数据,暗示着这题不寻常的写法——暴搜
递归求所有点的排列(显然15是不会爆的
这样的就把点的权值固定了
然后每次求出的排列求最小生成树,求出最小的边权和
再用求出的点权和与边权和的比值更新答案,记录最小的生成树
因为是按照顺序递归的,当比率相同时不用更新答案就可以保证生成树字典序最小
#include
#include
using namespace std;
int n,m,ss,nod,edg=10000;
int d[20],cnt,f[20];
struct cv{
int ed,x,y;
}e[400];
bool comp(cv a,cv b){
return a.ed0) node+=d[i];
}
for (int i=1,j=0;i<=cnt&&j=m){
tree(s);
return;
}
if (dep>=n) return;
dfs(dep+1,k+1,s|1<0)
printf("%d ",i);
}
一家软件开发公司有两个项目,并且这两个项目都由相同数量的m个子项目组成,对于同一个项目,每个子项目都是相互独立且工作量相当的,并且一个项目必须在m个子项目全部完成后才算整个项目完成。
这家公司有n名程序员分配给这两个项目,每个子项目必须由一名程序员一次完成,多名程序员可以同时做同一个项目中的不同子项目。
求最小的时间T使得公司能在T时间内完成两个项目。
m(1<=n<=100,1<=m<=100)。
其实仔(sui)细(bian)思(xiang)考(xiang)可以得出,题目就是要求一个所有程序员中最大的完成时间最少的方案,求这个最小的最大完成时间
于是就选择二分答案,dp判断答案正确性
f [ i ] [ j ] f[i][j] f[i][j]表示第i个程序员,第一个任务完成了j个,还可以完成最多个数的第二个任务
f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j − k ] + ( m i d − a [ i ] ∗ k ) / b [ i ] ) f[i][j]=max(f[i-1][j-k]+(mid-a[i]*k)/b[i]) f[i][j]=max(f[i−1][j−k]+(mid−a[i]∗k)/b[i])注意不要让f出现负数的情况即转移时要保证 k ∗ a [ i ] < = m i d k*a[i]<=mid k∗a[i]<=mid
#include
#include
#include
using namespace std;
int n,m,l,r;
int a[105],b[105];
int f[105][105];
void read(){
scanf("%d%d",&n,&m);
int xa=0,xb=0;
for (int i=1;i<=n;i++){
scanf("%d%d",&a[i],&b[i]);
xa=(xa=m) return 1;
return 0;
}
void bs(){
int t;
while (l<=r){
int mid=(l+r)/2;
if (dp(mid)) t=mid,r=mid-1;else l=mid+1;
}
printf("%d",t);
}
int main(){
freopen("company.in","r",stdin);
freopen("company.out","w",stdout);
read();
bs();
}
你是一艘战列巡洋舰的引擎操作人员,这艘船的船员在空间中侦测到了一些无法辨识的异常信号。你的指挥官给你下达了命令,让你制定航线,驾驶战列巡洋舰到达那里。
船上老旧的曲速引擎的速度是0.1AU/s。然而,在太空中分布着许多殖民星域,这些星域可以被看成一个球。在星域的内部,你可以在任何地方任意次跳跃到星域内部的任意一个点,不花费任何时间。
你希望算出到达终点的最短时间。
每个输入文件至多包含10 个测试数据。
对于10% 的数据,n = 0。
对于30% 的数据,0<=n<=10。
对于100% 的数据,0<=n<=100,所有坐标的绝对值<=10000 ,半径r<=10000。
你可以认为,你所在的星区的大小为无限大。
虽然是三维的地图,但是可以转化成有n个点的无向图
星球与星球的距离是球心距离减去半径,起点终点也算做半径为0的星球
然后随便最短路,弗洛伊德spfaDij随便跑
我一开始老错,最后发现是Floyed打炸??
原来Floyed原理是枚举中间点更新枚举出来的路径,也就是说中间点k应放在第一重循环
#include
#include
#include
using namespace std;
int n,m;
int x[105],y[105],z[105],r[105];
double a[105][105];
double kk(int x,int y,int z,int a,int b,int c,int r,int d){
double cd=sqrt((x-a)*(x-a)+(y-b)*(y-b)+(z-c)*(z-c));
cd=(double)cd-r-d;
if (cd<0) return 0;
return cd;
}
int main(){
freopen("warp.in","r",stdin);
freopen("warp.out","w",stdout);
while (1){
scanf("%d",&n);
if (n==-1) break;
for (int i=1;i<=n;i++){
scanf("%d%d%d%d",&x[i],&y[i],&z[i],&r[i]);
}
scanf("%d%d%d",&x[0],&y[0],&z[0]);
r[n+1]=0;
scanf("%d%d%d",&x[n+1],&y[n+1],&z[n+1]);
for (int i=0;i<=n+1;i++)
for (int j=0;j<=n+1;j++)
a[i][j]=a[j][i]=kk(x[i],y[i],z[i],x[j],y[j],z[j],r[i],r[j]);
for (int i=0;i<=n+1;i++)
for (int j=0;j<=n+1;j++)
if (i!=j)
for (int k=0;k<=n+1;k++)
if (j!=k&&i!=k&&a[i][k]+a[k][j]
Gabiluso是最伟大的间 谍之一。现在,他试图完成一个“不可能完成”的使命――减缓Colugu的军 队到达机场的时间。Colugu有n个公共汽车站和m条道路。每条道路直接连接两个巴士站,所有的道路都是单向的。为了保持空气洁净,政 府禁 止所有军 用 车辆,因此,军队必须乘搭巴士去机场。两个巴士站之间,可能有超过一条道路。如果一个公共汽车站被破坏时,所有连接该站的道路将无法运作。Gabiluso需要做的是 摧 毁 了一些公共汽车站,使军 队无 法在K分钟内到达机场。一辆公交车通过一条道路,都是一分钟。所有巴士站的编号从1到n。1号巴士站是在军营,第n号站是机场。军队始终从第一站出发。第一站和第n站不能被破坏,这里有大量的防御力量。当然也没有从第一站到第n站的道路。
请帮助Gabiluso来计算能完成使命所需摧 毁的最低数目的巴士站。
第一行包含三个整数n,m,k (2 接下来m行,每行2个整数s和f,表示从站s到站f有一条路。 50的数据暗示着这道题不同寻常的写法——我当时就想,要么暴搜,要么状压DP 然后它就真的暴搜了。。。 然后它就过了???
每次都跑最短路它真的没有炸。。。
就每次都跑最短路,然后枚举删除最短路经过的点,递归枚举,如果最短路长度>k就更新答案并退出,算是找到一个方案#include