P2502 [HAOI2006]旅行

时间:2022-12-22 19:06:09

P2502 [HAOI2006]旅行
有些问题光靠直觉是不靠谱的,必须有简单的证明,要么就考虑到所有情况。
这个题我想的是要么见最小生成树,要么建最大生成树,哎,我sb了
一种很简单的情况就能卡掉
在最小生成树中,Min为a,它有重边,b比a大,而且b依然是Min,那么此时答案就会更优。
正解就是枚举每一个边(从大到小),然后加边,直到联通,不断更新答案
时间复杂度为O(m^2)

这是一开始的错误代码:

 #include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<set>
#include<map>
#include<stack>
#include<cstring>
#define inf 2147483647
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,nl,mid,l,r
#define rson rs,mid+1,nr,l,r
#define N 100010
#define For(i,a,b) for(register long long i=a;i<=b;i++)
#define p(a) putchar(a)
#define g() getchar() using namespace std; long long n,m;
long long x,y,v;
long long s,t,Max,Min,cnt;
bool vis[];
long long ans[];
long long d[];
bool flag; struct node{
long long n;
long long v;
node *next;
}*e[]; struct kru{
long long l;
long long r;
long long v;
}E[]; void in(long long &x){
long long y=;
char c=g();x=;
while(c<''||c>''){
if(c=='-')y=-;
c=g();
}
while(c<=''&&c>=''){
x=(x<<)+(x<<)+c-'';c=g();
}
x*=y;
}
void o(long long x){
if(x<){
p('-');
x=-x;
}
if(x>)o(x/);
p(x%+'');
} bool cmp1(kru a,kru b){
return a.v<b.v;
} bool cmp2(kru a,kru b){
return a.v>b.v;
} void push(long long x,long long y,long long v){
node *p;
p=new node();
p->n=y;
p->v=v;
if(e[x]==NULL)
e[x]=p;
else{
p->next=e[x]->next;
e[x]->next=p;
}
} long long find(long long x){
if(d[x]==x)return x;
return d[x]=find(d[x]);
} void build1(){
For(i,,n)
d[i]=i;
For(i,,m){
long long t1=find(E[i].l);
long long t2=find(E[i].r);
if(d[t1]!=d[t2]){
d[t1]=t2;
}
}
} void build2(){
For(i,,n)
e[i]=NULL;
For(i,,m){
if(d[E[i].l]==d[E[i].r]){
push(E[i].l,E[i].r,E[i].v);
push(E[i].r,E[i].l,E[i].v);
}
}
} void dfs(long long now,long long Max,long long Min){
if(now==t){
For(i,,){
if(Max%i==&&Min%i==){
Max/=i;
Min/=i;
}
}
ans[++cnt]=Max;ans[++cnt]=Min;
flag=true;
return;
}
for(register node *i=e[now];i;i=i->next){
if(!vis[i->n]){
vis[i->n]=true;
dfs(i->n,max(Max,i->v),min(Min,i->v));
vis[i->n]=false;
}
if(flag)return;
}
} int main(){
in(n);in(m);
For(i,,m){
in(x);in(y);in(v);
E[i].l=x;
E[i].r=y;
E[i].v=v;
}
in(s);in(t);
//跑最小生成树
sort(E+,E+m+,cmp1);
build1();
For(i,,n)
d[i]=find(d[i]);
if(d[s]!=d[t]){
cout<<"IMPOSSIBLE";
return ;
}
build2();
flag=false;
dfs(s,-inf,inf); sort(E+,E+m+,cmp2);
build1();
For(i,,n)
d[i]=find(d[i]);
build2();
For(i,,n)
vis[i]=false;
flag=false;
dfs(s,-inf,inf);
// For(i,1,cnt){
// o(ans[i]);p('\n');
// } if(cnt==||double(ans[])/double(ans[])<=double(ans[])/double(ans[])){
if(ans[]%ans[]==)
o(ans[]/ans[]);
else
cout<<ans[]<<"/"<<ans[];
}
else
if(ans[]%ans[]==)
o(ans[]/ans[]);
else
cout<<ans[]<<"/"<<ans[];
return ;
}

对了30分

正解:

 #include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<set>
#include<map>
#include<stack>
#include<cstring>
#define inf 2147483647
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,nl,mid,l,r
#define rson rs,mid+1,nr,l,r
#define N 100010
#define For(i,a,b) for(register int i=a;i<=b;i++)
#define p(a) putchar(a)
#define g() getchar() using namespace std;
int n,m;
int d[];
int l,r,v;
int s,t;
int x,y,z;
struct kru{
int l;
int r;
int v;
bool operator < (const kru &temp)const{
return v>temp.v;
}
}e[]; void in(int &x){
int y=;
char c=g();x=;
while(c<''||c>''){
if(c=='-')y=-;
c=g();
}
while(c<=''&&c>=''){
x=(x<<)+(x<<)+c-'';c=g();
}
x*=y;
}
void o(int x){
if(x<){
p('-');
x=-x;
}
if(x>)o(x/);
p(x%+'');
} int find(int x){
if(d[x]==x)return x;
return d[x]=find(d[x]);
} int gcd(int x,int y){
return y==?x:gcd(y,x%y);
} int main(){
in(n);in(m);
For(i,,m){
in(l);in(r);in(v);
e[i].l=l;e[i].r=r;e[i].v=v;
}
in(s);in(t);
x=inf;y=; sort(e+,e+m+); For(i,,m){ For(ii,,n)
d[ii]=ii; For(j,i,m){ int t1=find(e[j].l);
int t2=find(e[j].r);
if(t1!=t2)
d[t1]=t2;
// For(k,1,n)
// d[k]=find(d[k]);
if(find(s)==find(t)){
if(double(e[i].v)/double(e[j].v)<double(x)/double(y)){
// cout<<double(e[i].v)/double(e[j].v)<<endl;
x=e[i].v;y=e[j].v;
}
break;
}
}
}
if(x/y==inf){
cout<<"IMPOSSIBLE";
return ;
}
z=gcd(x,y);
x/=z;y/=z;
if(x%y==)
o(x/y);
else
cout<<x<<"/"<<y;
return ;
}

P2502 [HAOI2006]旅行的更多相关文章

  1. P2502 &lbrack;HAOI2006&rsqb;旅行——暴力和并查集的完美结合

    P2502 [HAOI2006]旅行 一定要看清题目数据范围再决定用什么算法,我只看着是一个蓝题就想到了记录最短路径+最小生成树,但是我被绕进去了: 看到只有5000的边,我们完全可以枚举最小边和最大 ...

  2. 洛谷P2502&lbrack;HAOI2006&rsqb;旅行

    题目: Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光.Z小镇附近共有N个景点(编号为1,2,3,-,N),这些景点被M条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路.也许 ...

  3. luogu题解P2502&lbrack;HAOI2006&rsqb;旅行--最小生成树变式

    题目链接 https://www.luogu.org/problemnew/show/P2502 分析 一个很\(naive\)的做法是从\(s\)到\(t\)双向BFS这当然会TLE 这时我就有个想 ...

  4. luogu P2502 &lbrack;HAOI2006&rsqb;旅行

    传送门 边数只有5000,可以考虑\(O(m^2)\)算法,即把所有边按边权升序排序,然后依次枚举每条边\(i\),从这条边开始依次加边,加到起点和终点在一个连通块为止.这个过程可以用并查集维护.那么 ...

  5. P2502 &lbrack;HAOI2006&rsqb;旅行 并查集

    题目描述 Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光.Z小镇附近共有N个景点(编号为1,2,3,…,N),这些景点被M条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路.也 ...

  6. P2502 &lbrack;HAOI2006&rsqb;旅行 最小生成树

    思路:枚举边集,最小生成树 提交:1次 题解:枚举最长边,添加较小边. #include<cstdio> #include<iostream> #include<algo ...

  7. BZOJ 1050 &lbrack;HAOI2006&rsqb;旅行comf

    1050: [HAOI2006]旅行comf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1889  Solved: 976[Submit][Sta ...

  8. BZOJ 1050&colon; &lbrack;HAOI2006&rsqb;旅行comf&lpar; 并查集 &rpar;

    将edge按权值排序 , O( m² ) 枚举边 , 利用并查集维护连通信息. ------------------------------------------------------------ ...

  9. 1050&colon; &lbrack;HAOI2006&rsqb;旅行comf

    1050: [HAOI2006]旅行comf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1495  Solved: 737[Submit][Sta ...

随机推荐

  1. android 插件化 模块化开发

    http://blog.csdn.net/o1587790525/article/details/11891997 Android 插件化架构设计  http://www.iqiyi.com/w_19 ...

  2. BZOJ 1901 Zju2112 Dynamic Rankings

    树阵主席设置树.维护间隔动态K大. .. ZOJ到空间太小,太大,仅仅能到BZOJ上交 1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memor ...

  3. freemarker自定义标签报错(八)

    1.错误描述 freemarker.core.ParseException: Token manager error: freemarker.core.TokenMgrError: Unknown d ...

  4. request&period;getParameter&lpar;&rpar;在get和post方法中文乱码问题

    乱码原因:Http请求传输时将url以ISO-8859-1编码,服务器收到字节流后默认会以ISO-8859-1编码来解码成字符流(造成中文乱码) post请求: 假设提交请求的jsp页面是UTF-8编 ...

  5. gradle用户目录本地库移动设置

    gradle被越来越多的程序开发人员使用来构件项目代码,使用gradle依赖的第三方jar包有时候非常占空间,默认这样的用户本地库目录(缓存目录)在系统盘上,我们可以修改用户目录到其它盘上 工具/原料 ...

  6. Spring Boot 2&period;1&period;0 已发布,7 个重大更新!

    距离<重磅:Spring Boot 2.0 正式发布!>已经过去大半年了,而 Spring Boot 2.1.0 在 10 月底就发布了,我们来看下 Spring Boot 2.1.0 都 ...

  7. C&num;中当程序的访问权限不足时,Directory&period;Exists和File&period;Exists方法不会抛出异常报错

    有些时候,我们开发的C#应用程序的执行账号,可能没有对一些文件夹和文件的访问权限,当我们使用Directory.Exists和File.Exists方法去判断这些文件夹和文件是否存在的时候,Direc ...

  8. Linux命令之如何从普通用户切换至管理员用户

    普通用户,标志是一个$符号 管理员用户,标志是一个#符号 我要切换,敲打命令  sudo su - 然后输入你的管理员用户的密码(输入密码的时候是不可见的) 然后你就切换到#状态了.

  9. ORA-01950&colon; no privileges on tablespace XXX

    原因是该表空间没有为用户提供配额空间 alter user WANGGUAN quota unlimited on TS_ACCT_DAT_01; 在表空间中为该用户设置磁盘配额即可

  10. 【转】&period;Net 架构图