acwing 3626.三元一次方程
链接:https://www.acwing.com/problem/content/3629/
题目描述
解题思路
方程前面系数不变,那么直接进行一个环的循,枚举x和y的值就行,因为z=(n-3x-5y)/7
再看一下数据,n才1000,x最大为333,y最大为200,1000个数据复杂度就是O(333*200 *1000)
也就是O(6e7),时间绝对够
结束,没难点不用上代码
acwing 3627.最大差值
链接:https://www.acwing.com/problem/content/description/3630/
题目描述
解题思路
因为最小值最小只能为0,所以直接找到k项最大的数加到最大值上就行了
实际就是,给定一个长度为n的非负整数序列,让你求出前k+1项最大值的和
所以sort一遍再for循环1~k+1加起来就行了
结束,没难点不用上代码
acwing 3268.边的删减
链接:https://www.acwing.com/problem/content/description/3631/
题目描述
解题思路
最短路树
最短路树是由每个点到起点的最短路径组成的,存储着每个点的最短路径
如果一个点有多条最短路,那么只用随便保留一个就行了
一个无向图中,只要最短路树上的边没被删除,那么这个点离起点的最短距离也不变
也就是说,除了最短路树上的边,其他边都是无用的,可以随便删
如果能保留的边不够组成一个最短路树,那么“优秀点”的数量就是能保留的边数k,因为最短路树少一条边就少一个叶子结点
那么我们只用求出最短路树,然后从根节点开始从前往后尽可能多的保留最短路树上的边就行了
结束,上代码
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<LL,int> PII;
const int N=1e5+10,M=2e5+10;
int n,m,k;
int head[N],e[M],ne[M],w[M],idx;
int id[M];
LL dis[N];//边是1e9,所以最短距离有可能爆int
bool vis[N];
vector<int> ans;
void add(int a,int b,int c,int d) // 添加一条边a->b,边权为c
{
e[idx]=b;
w[idx]=c;
id[idx]=d;
ne[idx]=head[a];
head[a]=idx++;
}
void dijkstra() // 求1号点到n号点的最短路距离
{
memset(dis,0x3f,sizeof(dis));
dis[1] = 0;
priority_queue<PII, vector<PII>, greater<PII>> heap;
heap.push(make_pair(0, 1));
while(heap.size())
{
PII t=heap.top();
heap.pop();
int x=t.second;
if(vis[x]) continue;
vis[x]=true;
for (int i=head[x];i!=-1;i=ne[i])
{
int j=e[i];
//cout<<i<<" "<<x<<" "<<j<<endl;
if (dis[j]>dis[x]+w[i])
{
dis[j]=dis[x]+w[i];
heap.push(make_pair(dis[j],j));
}
}
}
}
void dfs(int x){
vis[x]=true;
for(int i=head[x];i!=-1;i=ne[i]){
int j=e[i];
//cout<<w[i]<<" "<<dis[i]<<" "<<dis[j]<<endl;
if(!vis[j]&&dis[j]==dis[x]+w[i]){
if(ans.size()<k) ans.push_back(id[i]);
dfs(j);
}
}
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c,i);
add(b,a,c,i);
}
dijkstra();
memset(vis,0,sizeof(vis));
dfs(1);
//for(int i=1;i<=n;i++) cout<<dis[i]<<endl;
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++) printf("%d ",ans[i]);
return 0;
}