Codeforces449A Jzzhu and Chocolate && 449B Jzzhu and Cities

CF挂0了,简直碉堡了。两道题都是正确的思路但是写残了。写个解题报告记录一下心路历程。

A题问的是 一个n*m的方块的矩形上切k刀,最小的那一块最大可以是多少。不难发现如果纵向切k1刀,横向切k2刀,那么答案应该是 (n/(k1+1)) * (m/(k2+1)),除法是取整的。虽然是取整,但是不难发现其实就是要(k1+1)*(k2+1)最小,根据均值不等式,k1+k2=k(定值) k1==k2的时候(k1+1)*(k2+1)=k1*k2+k1+k2+1=k1*k2+k+1应该是取最大值,所以当k1,k2越接近两端的时候这个值才会最小,所以我们总是先把某一维的切掉,然后再考虑剩下那一维。比赛的时候手残写错了,哎。。。

B题问的是给你一个图,一些是普通边,一些是train route边,train route边是从首都1连到其它点的,问的是train route边最多可以去掉多少条使得每个点的最短路径长不变。思路就是如果某个点我们可以通过走别的点到达的话,那么这条边是不需要的,留边的时候更新ans我写漏了,导致答案小了很多。

#pragma warning(disable:4996)
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;

#define ll long long
#define maxn 105000
#define inf 10000000000000000LL

int n, m, k;

struct Edge
{
	int v;
	ll w;
	Edge(int vi, ll wi) : v(vi), w(wi){}
	Edge(){}
};

vector<Edge>G[maxn];
ll dis2[maxn];
ll ans = 0;

ll d[maxn];
bool in[maxn];
void spfa()
{
	memset(d, 0x3f, sizeof(d));
	memset(in, 0, sizeof(in));
	queue<int> que;
	que.push(1); in[1] = true;
	d[1] = 0;
	while (!que.empty()){
		int u = que.front(); que.pop(); in[u] = false;
		for (int i = 0; i < G[u].size(); i++){
			int v = G[u][i].v; ll w = G[u][i].w;
			if (d[u] + w < d[v]){
				d[v] = d[u] + w;
				if (!in[v]) que.push(v), in[v] = true;
			}
		}
	}
}

ll d2[maxn];
bool upd[maxn];

void spfa2()
{
	memset(d2, 0x3f, sizeof(d2));
	memset(in, 0, sizeof(in));
	queue<int> que;
	que.push(1); d2[1] = 0; in[1] = true;
	for (int i = 2; i <= n; i++){
		if (dis2[i] < d[i]){
			que.push(i); in[i] = true; d2[i] = dis2[i];
		}
	}
	while (!que.empty()){
		int u = que.front(); que.pop(); in[u] = false;
		for (int i = 0; i < G[u].size(); i++){
			int v = G[u][i].v; ll w = G[u][i].w;
			if (d2[u] + w < d2[v]){
				d2[v] = d2[u] + w;
				if (!in[v]) que.push(v), in[v] = true;
				if (upd[v]) {
					++ans; upd[v] = false;
				}
			}
			else if (d2[u] + w == d2[v]){
				if (upd[v]) {
					++ans; upd[v] = false;
				}
			}
		}
	}
}

int main()
{
	while (cin >> n >> m >> k){
		for (int i = 0; i <= n; i++) G[i].clear();
		memset(dis2, 0x3f, sizeof(dis2));
		ans = 0;
		int ui, vi; ll wi;
		for (int i = 0; i < m; i++){
			scanf("%d%d%I64d", &ui, &vi, &wi);
			G[ui].push_back(Edge(vi, wi));
			G[vi].push_back(Edge(ui, wi));
		}
		spfa();
		memcpy(dis2, d, sizeof(dis2));
		memset(upd, 0, sizeof(upd));
		int si; ll yi;
		for (int i = 0; i < k; i++){
			scanf("%d%I64d", &si, &yi);
			if (dis2[si] <= yi) ++ans;
			else {
				dis2[si] = yi;
				if (upd[si]) {
					++ans;
				}
				upd[si] = true;
			}
		}
		spfa2();
		cout << ans << endl;
	}
	return 0;
}

Codeforces449A Jzzhu and Chocolate && 449B Jzzhu and Cities,布布扣,bubuko.com

时间: 2024-10-17 01:39:15

Codeforces449A Jzzhu and Chocolate && 449B Jzzhu and Cities的相关文章

Codeforces 449B Jzzhu and Cities(最短路)

题目链接:Codeforces 449B Jzzhu and Cities 题目大意:Jzzhu是一个国家的总统,这个国家有N座城市,以1为首都,已经存在了M条公路,给定M条路.并且还有K条铁轨,铁轨均有首都出发,连接si,距离为yi.现在Jzzhu想要节省经费,拆除一些铁轨,问说最多能拆除多少个铁轨,要求每座城市与首都的最短距离不变. 解题思路:最短路,多加一个标记数组,每个si标记1,如果这些点的最短距离被更新,则将对应si的标记清为0,最后统计一下剩余的标记,即为不能拆除的铁轨. #inc

CodeForces 449A - Jzzhu and Chocolate

传送门:Jzzhu and Chocolate 题意: 给出一个N * M的矩阵,给K个操作,每次操作可以横/竖切割矩阵,最后求K次切割之后,矩阵最小的那块面积最大是多少? 分析: 按照题意,题目求的结果是:(最小的面积,最大是多少),那么可以想到,K次切割之后尽量使得每个块的面积相等,某些块比较大(因为不一定能平均分),那么就可以使得最小的那块面积最大了. 然后如何切割呢? 因为有横竖两个切割方法,那么我们可以设X为横切割数,Y为竖切割数,其中(0 <= X, Y <= K),因为最多对一个

Codeforces Round #257 (Div. 2)449A - Jzzhu and Chocolate(贪心、数学)

题目链接:http://codeforces.com/problemset/problem/449/A ---------------------------------------------------------------------------------------------------------------------------------------------------------- 欢迎光临天资小屋:http://user.qzone.qq.com/593830943

449A - Jzzhu and Chocolate 贪心

一道贪心题,尽量横着切或竖着切,实在不行在交叉切 #include<iostream> #include<stdio.h> using namespace std; int main(){ // freopen("in.txt","r",stdin); long long n,m,k; while(cin>>n>>m>>k){ if((n+m-2)<k){ printf("-1\n"

(CF#257)C. Jzzhu and Chocolate

Jzzhu has a big rectangular chocolate bar that consists of n?×?m unit squares. He wants to cut this bar exactly k times. Each cut must meet the following requirements: each cut should be straight (horizontal or vertical); each cut should go along edg

Codeforces 450C:Jzzhu and Chocolate(贪心)

C. Jzzhu and Chocolate time limit per test: 1 seconds memory limit per test: 256 megabytes input: standard input output: standard output Jzzhu has a big rectangular chocolate bar that consists of \(n?×?m\) unit squares. He wants to cut this bar exact

CodeForces 449B - Jzzhu and Cities

传送门:Jzzhu and Cities 题意: 题意一定要看仔细,这里说一个国家,有N个城市,城市与城市之间有M条路,距离为W,编号为1的城市是首都,1和K个城市有火车道,距离为X 现在国家要节省开支,想把其中部分铁路关闭,但是又想关闭之后从首都到每一个城市本来的最短距离不变,求最多能关闭多少条铁路. 分析: 注意最重要的几点: 1.求关闭最多的铁路 2.关闭之后,从首都到每一个城市的最短距离不变. 3.从首都到某个城市的铁路可能有多条 算法: 很明显,求最短距离不变,那么就是最短路径问题,D

Codeforces 450 C. Jzzhu and Chocolate

//area=(n*m)/ ((x+1)*(k-x+1)) //1: x==0; //2: x=n-1 //3: x=m-1 # include <stdio.h> long long max(long long x,long long y) { return x>y?x:y; } int main() { long long n,m,k,sum,t,ans; scanf("%lld%lld%lld",&n,&m,&k); sum=n+m-2;

Codeforces Round #257 (Div. 2)

A.Jzzhu and Children 计算每个人会出现的轮次数,取最后一个且轮次数最大的,注意是用a[i]-1 % m,倒着扫一遍就行了 #include <iostream> #include <cstdio> #include <cstdlib> using namespace std; const int maxn = 100+10; int n, m; int a[maxn]; int main() { #ifdef LOCAL freopen("