Ingress
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 102400/65535 K (Java/Others)
Total Submission(s): 352 Accepted Submission(s): 159
Total Submission(s): 352 Accepted Submission(s): 159
Problem Description
Brickgao, who profited from your accurate calculating last year, made a great deal of money by moving bricks. Now he became ``gay shy fool'' again and recently he bought an iphone and was deeply addicted into a cellphone game called Ingress. Now he is faced with a problem so he turns to you for help again. We make some slight modifications based on the original rules, so please draw attention to the details below.
There are N portals (indexed from 1 to N ) around Brickgao's home, and he can get some substances called XM by hacking the portals. It's known that for each portal i , he can get Ai XM during the first hack, and after each hack, the amount of XM he will get during the next hack will decrease by Bi . If the amount of XM he can get is less than or equal to zero, Brickgao can't get XM from that portal anymore. For the i -th portal, if Ai=10,Bi=2 and he hacks 3 times, he will get 10, 8, 6 XM during each hack.
There are M bidirectional roads between some pairs of portals and between Brickgao's home and some portals. Now he is eager to start his Ingress journey from home and finally return home, but due to the extremely hot weather, Brickgao will feel sick when you hack more than K times or the distance he covers is more than L . So how much XM he can get at most during this journey?
There are N portals (indexed from 1 to N ) around Brickgao's home, and he can get some substances called XM by hacking the portals. It's known that for each portal i , he can get Ai XM during the first hack, and after each hack, the amount of XM he will get during the next hack will decrease by Bi . If the amount of XM he can get is less than or equal to zero, Brickgao can't get XM from that portal anymore. For the i -th portal, if Ai=10,Bi=2 and he hacks 3 times, he will get 10, 8, 6 XM during each hack.
There are M bidirectional roads between some pairs of portals and between Brickgao's home and some portals. Now he is eager to start his Ingress journey from home and finally return home, but due to the extremely hot weather, Brickgao will feel sick when you hack more than K times or the distance he covers is more than L . So how much XM he can get at most during this journey?
Input
The first line contains a single integer
T(T≤20)
, indicating the number of test cases.
The first line of each case are four integers N(1≤N≤16),M(0≤M≤N(N+1)2),K(1≤K≤50) and L(2≤L≤2000) .
The second line of each case contains N non-negative integers where the i -th denotes Ai(Ai≤500) .
The third line of each case contains N non-negative integers where the i -th denotes Bi(Bi≤50) .
Each of next M line contains 3 non-negative integers u,v(0≤u,v≤n) and c(0≤c≤1000) , denotes that there is a road with the length of c between the u -th and the v -th portal. If u or v equals to 0, it means Brickgao's home.
The first line of each case are four integers N(1≤N≤16),M(0≤M≤N(N+1)2),K(1≤K≤50) and L(2≤L≤2000) .
The second line of each case contains N non-negative integers where the i -th denotes Ai(Ai≤500) .
The third line of each case contains N non-negative integers where the i -th denotes Bi(Bi≤50) .
Each of next M line contains 3 non-negative integers u,v(0≤u,v≤n) and c(0≤c≤1000) , denotes that there is a road with the length of c between the u -th and the v -th portal. If u or v equals to 0, it means Brickgao's home.
Output
For each test case, output the case number first, then the amount of maximum XM Brickgao can get.
Sample Input
2 1 1 3 2 5 3 0 1 1 3 6 3 5 10 7 5 2 3 1 0 1 3 0 2 1 0 3 1 1 2 2 2 3 3 1 3 4
Sample Output
Case 1: 7 Case 2: 16
题意:略;
思路:
dp[i][j]:在状态i下,最终停留在j的最短距离。
状态转移方程:dp[i|(1<<k)][k] = min(dp[i|(1<<k)][k] , dp[i][j]+dis[j][k]) ((1<<k)&i != 0)
可以根据dp[i][j]+dis[j][0](最后要回到0)的值来判断所经过的路程时候满足要求。
若在状态i下所经过的最小路程满足要求,我们可以把在i状态下已经过的所有城市的结构体信息存入优先队列中。我们最多取k次,要最大,肯定取已经过的所有城市中a值最大的,取一次后那个城市的a值就要减去它的b,若a小于0就让a=0;若减掉后还最大,再取它......
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 20;
const int INF = 1e9+7;
typedef struct Point{
int a,b;
bool operator < (const Point& x) const{
return a<x.a;
}
};
int n,m,K,L;
Point p[N];
int map[N][N]; //输入的城市之间的联通情况和距离
int dp[1<<17][N];
int dis[N][N]; //每两个城市间的最短距离
int vis[1<<17]; //vis[i]: 第i种状态是否满足dis<=L
//初始化
void init()
{
memset(vis,0,sizeof(vis));
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
map[i][j]=INF;
map[i][i]=0;
}
}
//算每两个城市之间的最短距离(计算dis[ ][ ])
void SPFA(int x)
{
for(int i=0;i<=n;i++)
dis[x][i] = INF;
queue<int>q;
q.push(x);
dis[x][x]=0;
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=0;i<=n;i++)
{
if(map[now][i]==INF)
continue;
if(dis[x][i]>dis[x][now]+map[now][i])
{
dis[x][i]=dis[x][now]+map[now][i];
q.push(i);
}
}
}
}
int main()
{
int T;
int Case=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&n,&m,&K,&L);
init();
p[0].a=p[0].b=0;
int ans=0;
for(int i=1;i<=n;i++)
scanf("%d",&p[i].a);
for(int i=1;i<=n;i++)
scanf("%d",&p[i].b);
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(map[u][v]>w)
map[u][v]=map[v][u]=w;
}
//算dis[ ][ ]数组
for(int i=0;i<=n;i++)
SPFA(i);
for(int i=0;i<(1<<(n+1));i++)
for(int j=0;j<=n;j++)
dp[i][j]=INF;
dp[1][0]=0; //一开始必须从0出发
for(int i=1;i<(1<<(n+1));i++)
{
for(int j=0;j<=n;j++)
{
// j必须在i状态中为1
if( !(1<<j)&i )
continue;
//所经过的路程必须<=L
if(dp[i][j]+dis[j][0]<=L)
vis[i]=1;
for(int k=0;k<=n;k++)
{
//k需在i状态中为0
if( !((1<<k)&i) )
{
dp[i|(1<<k)][k] = min(dp[i|(1<<k)][k] , dp[i][j]+dis[j][k]);
}
}
}
if(vis[i])
{
priority_queue<Point>q;
for(int j=1;j<=n;j++)
{
if( (1<<j)&i )
q.push(p[j]);
}
if(q.empty())
continue;
int tmp=0;
for(int k=1;k<=K;k++)
{
Point now = q.top();
q.pop();
tmp+=now.a;
now.a -= now.b;
if(now.a<0)
now.a=0;
q.push(now);
}
ans=max(ans,tmp);
}
}
printf("Case %d: %d\n",Case++,ans);
}
return 0;
}