王为治 • 1年前
首先我们看到题目已经给出了代码了
但是我们可以用别的方法来做
例如图论
我们可以构建一个图,其中有3个点,1通向2,2通向3,并且将权值分别赋值为输入的两个数
再跑最短路算法就可以轻松通过此题
SPFA
#include <bits/stdc++.h>
//#pragma GCC optimize(2)
//#define int long long
#define endl '\n'
#define ll long long
#define ull unsigned long long
using namespace std;
const int N = 4000000;
const int M = 4000000;
int h[M],e[M],w[M],nxt[M],idx;
void add(int u, int v, int w_)
{
e[idx]=v;
w[idx]=w_;
nxt[idx]=h[u];
h[u]=idx++;
}
int n,m;
int dis[N],q[N],cnt[N];
bool vis[N];
bool flag = false;
void spfa(int st)
{
int f=0;
int t=0;
int tmp;
q[++t]=st;
dis[st]=0;
vis[st]=true;
int V,W;
while(f<t)
{
tmp = q[f+1];
vis[tmp]=false;
for(int i = h[tmp]; i != -1; i = nxt[i])
{
V = e[i];
W = w[i];
if(dis[V]>dis[tmp]+W)
{
dis[V]=dis[tmp]+W;
if(!vis[V])
{
//cout << 'k' << endl;
//cout << cnt[e[i]] << endl;
if(++cnt[V]>=n)
{
cout << "YES" << endl;
flag = true;
return;
}
vis[V]=true;
q[++t]=V;
}
}
}
f++;
}
}
void solve()
{
memset(e,0,sizeof(e));
memset(w,0,sizeof(w));
memset(nxt,0,sizeof(nxt));
memset(q,0,sizeof(q));
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
memset(dis,0x3f3f3f3f,sizeof(dis));
idx = 0;
flag = false;
int u,v,w_;
int st = 1;
n = 3;
int a__,b__;
cin >> a__ >> b__;
memset(h,-1,sizeof(h));
add(1,2,a__);
add(2,3,b__);
spfa(st);
cout << dis[3] << endl;
}
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T;
T = 1;
while(T--)
{
solve();
}
return 0;
}
DIJKSTRA
#include <bits/stdc++.h>
using namespace std;
struct edge
{
int to,dis,next;
};
edge e[500010];
int head[100010],dis[100010],cnt;
bool vis[100010];
int n,m,s;
void add_edge(int u, int v, int d)
{
cnt++;
e[cnt].dis = d;
e[cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt;
}
struct node{
int dis;
int pos;
bool operator <( const node &x)const
{
return x.dis < dis;
}
};
priority_queue<node> q;
void dijkstra()
{
dis[s]=0;
q.push((node){0,s});
while(!q.empty())
{
node tmp = q.top();
q.pop();
int x = tmp.pos, d = tmp.dis;
if(vis[x])continue;
vis[x]=true;
for(int i = head[x]; i ; i = e[i].next)
{
int y = e[i].to;
if(dis[y]>dis[x]+e[i].dis)
{
dis[y] = dis[x]+e[i].dis;
if(!vis[y])
{
q.push((node){dis[y],y});
}
}
}
}
}
signed main()
{
//cin >> n >> m >> s;
//memset(dis,0x3f3f3f3f,sizeof(dis));
int n = 3;
s = 1;
int a__, b__;
cin >> a__ >> b__;
for(int i = 0; i < 100010; i++)dis[i]=INT_MAX;
add_edge(1,2,a__);
add_edge(2,3,b__);
dijkstra();
cout << dis[3] << endl;
return 0;
}
评论:
不如使用线段树。
#include <bits/stdc++.h>
using namespace std;
#define int long long
inline int Read() {
int x = 0 , f = 1;
char c = getchar();
for( ; c < '0' || c > '9' ; c = getchar() ) f ^= ( c == '-' );
for( ; c >= '0' && c <= '9' ; c = getchar() ) x = ( x << 3 ) + ( x << 1 ) + ( c ^ 48 );
return f ? x : -x;
}
const int _ = 1e5 + 5;
struct SMT {
private:
struct Node {
Node *L , *R;
int l , r;
int sum , add;
Node( int l , int r ) : L(NULL),R(NULL),l(l),r(r),sum(0),add(0) {}
int len() {
return r - l + 1;
}
int mid() {
return l + ( r - l ) / 2;
}
void PushUp() {
sum = L->sum + R->sum;
}
void PushDown() {
L->sum += L->len() * add;
R->sum += R->len() * add;
L->add += add;
R->add += add;
add = 0;
}
};
public:
Node *root;
void Build( int l , int r , Node *&p , int a[] ) {
p = new Node( l , r );
if( l == r ) {
p->sum = a[ l ];
return;
}
Build( l , p->mid() , p->L , a );
Build( p->mid() + 1 , r , p->R , a );
p->PushUp();
}
void Add( int x , int y , int v , Node *p ) {
if( x <= p->l && p->r <= y ) {
p->sum += p->len() * v;
p->add += v;
return;
}
p->PushDown();
if( x <= p->mid() ) Add( x , y , v , p->L );
if( y > p->mid() ) Add( x , y , v , p->R );
p->PushUp();
}
int GetSum( int x , int y , Node *p ) {
if( x <= p->l && p->r <= y ) {
return p->sum;
}
p->PushDown();
int ans = 0;
if( x <= p->mid() ) ans += GetSum( x , y , p->L );
if( y > p->mid() ) ans += GetSum( x , y , p->R );
return ans;
}
} seg;
int a[_];
signed main() {
a[ 1 ] = Read() , a[ 2 ] = Read();
seg.Build( 1 , 2 , seg.root , a );
printf( "%lld\n" , seg.GetSum( 1 , 2 , seg.root ) );
return 0;
}
我觉得不如 Kruskal
#include <bits/stdc++.h>
using namespace std;
inline int read(){
int x=0;bool f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=0;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return f?x:-x;
}
struct edge{
int u,v,w;
bool operator<(edge x) const{
return w<x.w;
}
}a[10];
int A,B,f[114514],n=3,m=2,ans;
int fa(int x){return (f[x]^x)?f[x]=fa(f[x]):x;}
int main(){
A=read(),B=read();
a[1]={1,2,A},a[2]={2,3,B};
sort(a+1,a+m+1);
for(int i=1;i<=n;i++)
f[i]=i;
for(int i=1;i<=m;i++)
if(fa(a[i].u)^fa(a[i].v))
ans+=a[i].w,f[fa(a[i].u)]=fa(a[i].v);
printf("%d\n",ans);
return 0;
}