EXAM-2018-7-24
未完成
- [ ] G
签到水题 A J F
A:英文字母有2426个
J:注意long long
D:Transit Tree Path
我直接套了单源最短路的一个模板,有人用的是DFS,模板第一次用,记得是无向图。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
const long long INF=1e17;
long long dist[maxn];
#define ll long long
bool vis[maxn];
struct node
{
int v,c;
node(int _v=0,int _c=0):v(_v),c(_c){}
bool operator <(const node &r) const
{
return c>r.c;
}
};
struct edge
{
ll v,cost;
edge(ll _v=0,ll _cost=0):v(_v),cost(_cost){}
};
vector<edge>str[maxn];
void dijk(int n,int start)
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) dist[i]=INF;
priority_queue<node>q;
while(!q.empty())
{
q.pop();
}
dist[start]=0;
q.push(node(start,0));
node tmp;
while(!q.empty())
{
tmp=q.top();
q.pop();
int u=tmp.v;
if(vis[u]) continue;
vis[u]=true;
for(int i=0;i<str[u].size();i++){
int v=str[tmp.v][i].v;
ll cost=str[u][i].cost;
if(!vis[v]&&dist[v]>dist[u]+cost)
{
dist[v]=dist[u]+cost;
q.push(node(v,dist[v]));
}
}
}
}
void add(int u,int v,int w)
{
str[u].push_back(edge(v,w));
}
int main()
{
int n;
scanf("%d",&n);
int a,b,c;
for(int i=0;i<n-1;i++){
scanf("%d%d%d",&a,&b,&c);
add(b,a,c);
add(a,b,c);
}
int k,q;
scanf("%d%d",&k,&q);
dijk(n,q);
for(int i=1;i<=k;i++){
scanf("%d%d",&a,&b);
printf("%lld
",dist[a]+dist[b]);
}
return 0;
}
E Lemonade Line
完全是英语阅读理解,题目读不懂,看样例也很难看懂,其实代码很简单。
K 打地鼠游戏
单调队列,刚开始想复杂了,只要队列中有数比要插进来的数小就替换最小的
priority_queue<int, vector<int>, greater<int>>Q;
I 经营与开发
看了题解说什么正难则反一大堆,根本看不懂
终于找到一个有说服力的:
这个我对楼下做出点补充,记最终答案为ans,其实对于每个星球不管是维修还是资源型,都可以把对钻头的改变度记作一个常数k,而且k是有后效性的。我们先具一个i=4的例子,ans=wk1a1+wk1k2a2+wk1k2k3a3+wk1k2k3k4a4,即ans=w(k1a1+k1k2a2+k1k2k3a3+k1k2k3a4),进一步提公因式就是ans=w(k1(a[1]+k2(a[2]+k3(a[3]+k4a[4]))))(这叫什么数学名词来着,蒟蒻忘了),实际上对于每个a[i],a[i]前还要乘上一个符号变量t(维修+1,资源-1,不选乘0)。即ans=w(k1(t1a[1]+k2(t2a[2]+k3(t3a[3]+k4t4a[4]))))那么我们的题目就变为对每项选择最优的符号变量得出最大的答案值。照楼下的思路我们是要从最里面的括号开始推,确保每次括号里的值都最大。
这是因为我们要求的总问题就是使的w(内的值最大)。而每个阶段的决策是tia[i]+ki*(内的值)。因为后一项肯定为正,由最优子结构性质得(内的值一定是最大值)。这样以来楼下的思路就通了。