在上一回和上上回里我们知道Nettle在玩《艦これ》,Nettle在整理好舰队之后终于准备出海捞船和敌军交战了。
在这个游戏里面,海域是N个战略点(编号1..N)组成,如下图所示
其中红色的点表示有敌人驻扎,猫头像的的点表示该地图敌军主力舰队(boss)的驻扎点,虚线表示各个战略点之间的航线(无向边)。
在游戏中要从一个战略点到相邻战略点需要满足一定的条件,即需要舰队的索敌值大于等于这两点之间航线的索敌值需求。
由于提高索敌值需要将攻击机、轰炸机换成侦察机,舰队索敌值越高,也就意味着舰队的战力越低。
另外在每一个战略点会发生一次战斗,需要消耗1/K的燃料和子弹。必须在燃料和子弹未用完的情况下进入boss点才能与boss进行战斗,所以舰队最多只能走过K条航路。
现在Nettle想要以最高的战力来进攻boss点,所以他希望能够找出一条从起始点(编号为1的点)到boss点的航路,使得舰队需要达到的索敌值最低,并且有剩余的燃料和子弹。
特别说明:两个战略点之间可能不止一条航线,两个相邻战略点之间可能不止一条航线。保证至少存在一条路径能在燃料子弹用完前到达boss点。
输入
第1行:4个整数N,M,K,T。N表示战略点数量,M表示航线数量,K表示最多能经过的航路,T表示boss点编号, 1≤N,K≤10,000, N≤M≤100,000
第2..M+1行:3个整数u,v,w,表示战略点u,v之间存在航路,w表示该航路需求的索敌值,1≤w≤1,000,000。
输出
第1行:一个整数,表示舰队需要的最小索敌值。
Sample Input
5 6 2 5 1 2 3 1 3 2 1 4 4 2 5 2 3 5 5 4 5 3
Sample Output
3
这题本菜鸟不看题解根本想不到用二分(也许这就是菜鸟吧)
输入
第1行:4个整数N,M,K,T。N表示战略点数量,M表示航线数量,K表示最多能经过的航路,T表示boss点编号, 1≤N,K≤10,000, N≤M≤100,000
第2..M+1行:3个整数u,v,w,表示战略点u,v之间存在航路,w表示该航路需求的索敌值,1≤w≤1,000,000。
输出
第1行:一个整数,表示舰队需要的最小索敌值。
建立一个vector的二维数组里面存储node
qu[a][i].x 表示含义为a岛到i岛所需的索敌值
有了vector的帮助这题就很容易了。
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 struct node 8 { 9 int x,y; 10 }; 11 int n,m,k,t; 12 vector<node>qu[10010]; 13 int vis[10010]; 14 int bfs(int dis) 15 { 16 memset(vis,0,sizeof(vis)); 17 queue<int>q; 18 q.push(1); 19 while(!q.empty()){ 20 int cur=q.front(); 21 q.pop(); 22 if (cur==t) return 1; 23 if (vis[cur]==k) continue; 24 int len=qu[cur].size(); 25 for (int i=0 ;i<len ;i++){ 26 int temp=qu[cur][i].x; 27 if (vis[temp] || qu[cur][i].y>dis) continue; 28 vis[temp]=vis[cur]+1; 29 q.push(temp); 30 } 31 } 32 return 0; 33 } 34 int main() { 35 while(scanf("%d%d%d%d",&n,&m,&k,&t)!=EOF){ 36 int a,b,c,maxn=0; 37 for (int i=0 ;i<m ;i++){ 38 scanf("%d%d%d",&a,&b,&c); 39 node temp; 40 temp.x=b,temp.y=c; 41 qu[a].push_back(temp); 42 temp.x=a,temp.y=c; 43 qu[b].push_back(temp); 44 maxn=max(maxn,c); 45 } 46 int mid,l=0,r=maxn; 47 while(l<=r){ 48 mid=(l+r)/2; 49 if (bfs(mid)) r=mid-1; 50 else l=mid+1; 51 } 52 printf("%d ",l); 53 } 54 return 0; 55 }