派对选址

派对选址
(party.pas/c/cpp)
【题目描述】
在2022年,scu_acmers决定举行一个聚会,并且大多数老 scu_acmers队员已经收到了邀请函,包
括队员 onmylove,tanlinghang和zsasuke(scu_isap队的老队员)。
从 scu毕业已经 10年了,现在他们住在不同的城市。他们都非常傲慢,都认为在所有 scu_acmers
队员中,自己才是最擅长跑步的人。为了证明这一点,他们都决定花上几天时间跑向目的地(聚会所举
办的城市),并且为了节省体力,他们每个人都会选择最短的路线前往(可能存在多条最短路线,在这种
情况下,他们会随机选择其中的一条)。但是这会导致一系列问题:他们会偶然停下来休息,并且他们
一旦在同一条路上相遇,他们会停止前进,开始争吵谁才是最擅长跑步的人,彻底错过聚会。
Scu 的领导都是考虑周到的人,他们不想让任何一个人错过聚会,因此他们想要选择一个合适的聚
会城市,使得 scu_isap的队员们不会在中途相遇。但是他们都很忙,所以这个任务就交给你了。
【输入文件】
第一行两个正整数 N 和M,表示城市个数和道路条数(onmylove 住在城市 1,tanlinghang 住在城市 2,
zsasuke 住在城市 3),接下来 M行,每行包含三个正整数a,b,c(1≤a,b≤N,1≤c≤10,b≠a,并且任意
两个城市之间至多只有一条道路直接相连),表示从a到b 要花费 c天,从b到 a要花费 c天。
【输出文件】
如果不存在这样的城市,输出仅一行”impossible”(不含引号),否则,第一行输出一个数 P,表示有
P 个城市满足要求,接下来一行,P个用空格隔开的数,表示满足条件的城市编号(升序输出)。
【样例输入】
5 5
1 5 2
4 5 2
5 2 3
2 4 5
3 4 1

【样例输出】
1
5

【样例解释】
我们不能选择 4 号城市。假如我们选择 4 号城市,那么,onmylove 的路线是1-5-4;tanlinghang 的是
2-5-4或2-4;如果tanlinghang选择2-5-4,他将与onmylove在5和4之间的道路上相遇,然后争吵。

【数据规模】
对于10%的数据: 3≤N≤5;1≤M≤10;
对于100%的数据:3≤N≤3000;1≤M≤200000;

派对选址
题目看起来很难的样子,真心不会做。。。
但是,题目中有个突破口——某个人有多条路径可走,而且不能和别人的最短路径有交集——看似使题目变得很难,实际上,要是有交集的话,那么从交点延伸过去的,以这条路为中间路径的某两点之间的最短路上的点(在交点之后)肯定不可行,例子见下——


假设a在1,b在2,c在3。
b和c在4的时候就有了交集,说明在6,7,8,9,10,5,1这几个点是不可以设置Party的。
那么剩下了2,3,4进行判断——
2:a与c会提前相交于4,所以不行;
3:a与b会提前相交于4,所以不行;
4:可行。
(讲的很辣鸡,不懂没关系)
实际上,我们可以先把从1,2,3到每个点的最短路刷出来。
那么,我们肯定要判断每一个点是否可行。
比如我们判断6是否可行——
我们发现,不管点2,点3是否有其他分支,他们总是可能聚集到点4,那么点6自然而然也就不行了。
其实,每当枚举一个点i时,与他所有相邻的点,比如j,如果同时有两个人(a,b,c中的)dis[i]==dis[j]+f[j][i],说明什么?这两个人都有可能经过j--i这条路,那么不就不可以了?(话说前面我在干什么!!!)归根到底,某一个点是否能举办Party,不是看这个点,而是看与它相邻的点和对应的边的情况(因为如果两个人有交点,交点却就是终点,那也是可以的啊)。好了不说了,不然要祸害苍灵了。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=3005,maxe=400005;
 6 int n,m,w[maxe],nxt[maxe],son[maxe],lnk[maxn];
 7 int dis[4][maxn],q[maxn];
 8 int tot=0,h,t,INF;
 9 bool vis[maxn];
10 int ans[maxn];
11 inline int read(){
12     int x=0,f=1; char ch=getchar();
13     while (ch<‘0‘||ch>‘9‘){if (ch==‘-‘) f=-f; ch=getchar();}
14     while (ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
15     return x*f;
16 }
17 void add(int x,int y,int z){
18     nxt[++tot]=lnk[x],son[tot]=y,w[tot]=z,lnk[x]=tot;
19 }
20 void spfa(int fl){
21     memset(dis[fl],63,sizeof dis[fl]),INF=dis[fl][0];
22     memset(vis,0,sizeof vis);
23     memset(q,0,sizeof q);
24     dis[fl][fl]=0,vis[fl]=1,q[1]=fl,h=0,t=1;
25     while (h!=t){
26         h=(h+1)%maxn,vis[q[h]]=0;
27         for (int j=lnk[q[h]]; j; j=nxt[j])
28         if (dis[fl][son[j]]>dis[fl][q[h]]+w[j]){
29             dis[fl][son[j]]=dis[fl][q[h]]+w[j];
30             if (!vis[son[j]]){
31                 t=(t+1)%maxn,q[t]=son[j],vis[son[j]]=1;
32                 if (dis[fl][q[(h+1)%maxn]]>dis[fl][q[t]]) swap(q[(h+1)%maxn],q[t]);
33             }
34         }
35     }
36 }
37 int main(){
38     n=read(),m=read();
39     for (int i=1; i<=m; i++){
40         int x=read(),y=read(),z=read();
41         add(x,y,z),add(y,x,z);
42     }
43     spfa(1),spfa(2),spfa(3);
44     for (int i=1; i<=n; i++)
45     if (!(lnk[i]==0||dis[1][i]==INF||dis[2][i]==INF||dis[3][i]==INF)){
46         bool flg=1;
47         for (int j=lnk[i]; j; j=nxt[j]){
48             int pre=son[j];
49             bool f1=dis[1][i]==dis[1][pre]+w[j],f2=dis[2][i]==dis[2][pre]+w[j],f3=dis[3][i]==dis[3][pre]+w[j];
50             if (f1+f2+f3>=2) flg=0;
51         }
52         if (flg) ans[++ans[0]]=i;
53     }
54     if (!ans[0]) printf("impossible");
55     else{
56         printf("%d\n",ans[0]);
57         for (int i=1; i<=ans[0]; i++) printf("%d ",ans[i]);
58     }
59     return 0;
60 }

时间: 2024-08-13 17:36:05

派对选址的相关文章

NYOJ---题目733万圣节派对

万圣节派对 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述 万圣节有一个Party,XadillaX显然也要去凑热闹了.因为去凑热闹的人数非常庞大,几十W的数量级吧,自然要进场就需要有门票了.很幸运的,XadillaX竟然拿到了一张真·门票!这真·门票的排列规则有些奇怪: 门票号是由0~6组成的六位数(0~6这几个数字可重用) 每一个门票号的每一位不能有三个连续相同的数字(如123335是不行的) 每一个门票号相邻的两位相差必须在四以下(≤4)(如016245是不行

利用高德地图完成用户地图选址,包括搜索位置和标签固定居中

这两天一直捣鼓着地图的选址功能,需要达到的要求是:1,能用户定位  2,大头针固定在地图中心,拖动地图停止后获取到该大头针的位置信息    3,能通过搜索框搜索到我们输入的地址 主要思路:大头针分为两个   一个是用户的位置大头针  另一个是所选取的位置的大头针(包括拖动后的大头针和搜索功能查找到位置的大头针,公用一个大头针  )并且两个大头针都成为控制器器属性. 我使用到的高德地图sdk是: 'AMap3DMap' , '5.2.1' #高德3D地图 'AMapSearch' , '5.2.1

cocos2d-x开发的《派对小游戏》-github源码分享

这是博主很久以前写的一个cocos2d-x跨平台小游戏,我称它为<派对小游戏>,现在分享给大家,希望对大家有所帮助的话. 项目源码地址:https://github.com/xiebaochun/partygame-cocos2d-x 游戏截图如下: 主页: 打地鼠 视觉空间 拖拖拉拉

【NOIP之旅】NOIP2014 day2 T1 无线网络发射器选址

1.无线网络发射器选址 (wireless.cpp/c/pas) [问题描述] 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129条东西向街道和129条南北向街道所形成的网格状,并且相邻的平行街道之间的距离都是恒定值1.东西向街道从北到南依次编号为0,1,2…128,南北向街道从西到东依次编号为0,1,2…128. 东西向街道和南北向街道相交形成路口,规定编号为x的南北向街道和编号为y的东西向街道形成的路口的坐标是(

【BZOJ1835】[ZJOI2010]base 基站选址 线段树+DP

[BZOJ1835][ZJOI2010]base 基站选址 Description 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村庄不超过Si的范围内建立了一个通讯基站,那么就成它被覆盖了.如果第i个村庄没有被覆盖,则需要向他们补偿,费用为Wi.现在的问题是,选择基站的位置,使得总费用最小. 输入数据 (base.in) 输入文件的第一行包含两个整数N,K,含义如上所述. 第

Android中级篇之百度地图SDK v3.5.0-一步一步带你仿各大主流APP地图定位移动选址功能

定位+移动选址 百学须先立志-学前须知: 我们经常在各大主流APP上要求被写上地址,如百度外卖.爱鲜蜂收货地址等等:其中他们大多数是可以让我们在地图上移动选址.就如下面这段GIF演示的一样: 尽信书,不如无书-能学到什么? 1.地图状态MapStatus类及监听setOnMapStatusChangeListener 2.定位LocationClient类 3.反地理编码GeoCoder类 工欲善其事必先利其器-申请Key 百度地图访问应用(AK)申请地址:http://lbsyun.baidu

洛谷 P2038 无线网络发射器选址

P2038 无线网络发射器选址 注意边界是否小于0 1 #include<bits/stdc++.h> 2 using namespace std; 3 int d,n,num[1000][1000],ans[1000][1000],tot,cnt,maxx; 4 int main() 5 { 6 scanf("%d",&d); 7 scanf("%d",&n); 8 memset(num,0,sizeof(num)); 9 memset

luogu P1821 [USACO07FEB]银牛派对Silver Cow Party

题目描述 One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A total of M (1 ≤ M ≤ 100,000) unidirectional (one-way roads connects pairs of farms; road i requires

一个实例学会LINGO之选址问题

代码如下: !选址问题;!吨公里和运费成正比; MODEL: Title Location Problem; sets: demand/1..6/:a,b,d;!定义a,b,d三个向量,大小为1x6; supply/1..2/:x,y,e; link(demand,supply):c;!定义c为一个矩阵,稠密集合,所以大小为demand x supply 即6x2;endsets data: a=1.25,8.75,0.5,5.75,3,7.25;!工地横坐标; b=1.25,0.75,4.75