第二次做此题:
在次做此题还是做了很长时间,问题在于枚举权限区间时用
for(int i = dfmin; i + m <= djmax: i++)
这事一个多么蠢的错误啊, 如果m很大时, 这个循环都不会执行。肯定是错的,
正确的做法是:
for(int i = 0; i <= m; i++) {
<span style="white-space:pre"> </span>if(dj[j] >= dj[1] - m + i && dj[j] <= dj[1] + i)
<span style="white-space:pre"> </span>true;
<span style="white-space:pre"> </span>else
<span style="white-space:pre"> </span>false;
就是一根为中心,左右权限变动范围在m内:
除这一点外没什么难的;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int M = 150;
const int MAX = 9999999;
int Map[M][M];
int node[M];
int value[M];
int level[M];
int dist[M];
int lmin, rmax;
int n, m, ans;
void init(){
ans = MAX;
rmax = 0;
lmin = MAX;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++)
Map[i][j] = MAX;
}
}
bool check(int x, int y){
if(level[x] >= level[1] - m + y && level[x] <= level[1] + y)
return true;
return false;
}
void Dijstra(int x){
int index, minn;
int vist[M];
for(int i = 1; i <= n; i++){
vist[i] = 0;
if(check(i, x)){
dist[i] = Map[1][i];
}else {
dist[i] = MAX;
}
}
dist[1] = 0;
vist[1] = 1;
for(int i =1; i <= n; i++){
minn = MAX;
for(int j = 1; j <= n; j++){
if(!vist[j] && dist[j] < minn){
minn = dist[j];
index = j;
}
}
if(minn == MAX)
break;
vist[index] = 1;
for(int k = 1; k <= n; k++){
if(!vist[k] && dist[k] > Map[index][k] + dist[index] && check(index, x) && check(k,x))
dist[k] = Map[index][k] + dist[index];
}
}
for(int i = 1; i <= n; i++){
ans = min(ans, dist[i] + value[i]);
}
}
int main()
{
int x;
int a, b;
while(scanf("%d%d", &m, &n)!= EOF){
init();
for(int i = 1; i <= n; i++){
scanf("%d%d%d", &value[i], &level[i], &x);
for(int j = 0; j < x; j++){
scanf("%d%d", &a, &b);
Map[i][a] = b;
}
}
for(int i = 0; i <= m; i++){
Dijstra(i);
}
printf("%d\n", ans);
}
return 0;
}
第一次做此题
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
/*
本题我开始认为是简单题,用动态规划轻松AC ,但是错几次后发现题意理解错了, 如 一号的等级是3 等级限制是1
认为在[2 4]间的等级都可以对换,结果可想而知, 真正题意是只选[2 3]的等级, 或[3 4]等级;
借鉴别人代码;下面就是 dijkastra算法了;
*/
const int MAX = 9999999;
int dp[105][105];
int vist[105];
struct node
{
int value;
int dj;
int num;
}s[105];
int n, m;
int t1, t2;
void init() {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
dp[i][j] = MAX;
}
}
}
int dijkastra() {
int cnt[105];
int dir[105];
int index;
int minn;
dir[1] = 0;
cnt[1] = 0;
for(int i = 2; i <= n; i++) {
dir[i] = MAX;
cnt[i] = 0;
}
for(int i = 1; i < n; i++) {
minn = MAX;
for(int j = 1; j <= n; j++)
{
if(vist[j] && cnt[j] == 0 && dir[j] < minn) {
index = j;
minn = dir[j];
}
}
cnt[index] = 1;
for(int k = 1; k <= n; k++) {
if(!cnt[k]&&vist[k] && dir[k] > dir[index] + dp[index][k])
dir[k] = dir[index] + dp[index][k];
}
}
minn = MAX;
for(int i = 1; i <= n; i++) {
dir[i] += s[i].value;
if(dir[i] < minn)
minn = dir[i];
}
return minn;
}
int main()
{
int hao, jinbi;
while(scanf("%d%d", &m, &n) != EOF) {
init();
for(int i = 1; i <= n; i++) {
scanf("%d%d%d", &s[i].value, &s[i].dj, &s[i].num);
for(int j = 1; j <= s[i].num; j++) {
scanf("%d%d", &hao, &jinbi);
dp[i][hao] = jinbi;
}
}
int ans = MAX;
for(int i = 0; i <= m; i++) {
memset(vist, 0, sizeof(vist));
for(int j = 1; j <= n; j++)
if(s[j].dj >= s[1].dj - m +i && s[j].dj <= s[1].dj + i)
vist[j] = 1;
int t = dijkastra();
if(t < ans)
ans = t;
}
printf("%d\n", ans);
}
return 0;
}