不正经的题解(但是能过

王为治  •  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;
}

ZZQ  •  1年前

%%%


kkksc03  •  1年前

orz


董乐  •  1年前

我觉得不如 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;
}

seanlsy  •  1年前

不如使用bdfs算法


水你啊  •  1年前

梁晨熙  •  1年前