csp杂记-资料

201612-4 压缩编码(DP)

#include<bits/stdc++.h>
using namespace std;
// 石子合并问题 总花费最小 
int n;
int t[1005];
int dp[1005][1005]; //dp[i][j]表示合并从i到j的单词所需要的最小花费 dp[1][n]为目标 
int sum[1005][1005];//sum[i][j]表示从i到j的单词权值和 
int main(){
	memset(dp,0x3f,sizeof(dp));
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>t[i];
	}
	for(int i=1;i<=n;++i){
		dp[i][i]=0;
		for(int j=i;j<=n;++j){
			sum[i][j]=sum[i][j-1]+t[j];
		} 
		dp[i][i+1]=sum[i][i+1];
	}
	for(int i=n-1;i>=1;--i){
		for(int j=i+1;j<=n;++j){
			for(int k=i;k<=j-1;++k){
				dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[i][j]);
			}
		}
	}
	cout<<dp[1][n];
	return 0;
}

201703-4 地铁修建(最小生成树Dijkstra)

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
struct Edge{
	int u,v,c;
	Edge(int uu,int vv,int cc){
		u=uu;
		v=vv;
		c=cc;
	}
	bool operator <(const Edge &e)const{
		return c > e.c;
	}
};
priority_queue<Edge> q;
int father[N];
int findFather(int x){
	if(father[x]==x){
		return x;		
	}
	int temp=findFather(father[x]);
	father[x]=temp;
	return temp;
}
int main(){
	int n,m,ans=0;
	cin>>n>>m;
	iota(father,father+n+1,0);
	while(m--){
		int a,b,c;
		cin>>a>>b>>c;
		q.push(Edge(a,b,c));
	}
	while(findFather(1)!=findFather(n)){
		Edge e=q.top();
		q.pop();
		int ua=findFather(e.u);
		int ub=findFather(e.v);
		if(ua!=ub){
			father[ub]=ua;
			ans=e.c;
		}
	}
	cout<<ans;
	return 0;
}

201709-4 通信网络(DFS)

#include<bits/stdc++.h>
using namespace std;
const int N=1005;
vector<int> g[N];
bool know[N][N];
bool vis[N];
void dfs(int x,int f){
	know[x][f]=know[f][x]=true;
	for(int i:g[x]){
		if(!vis[i]){
			vis[i]=true;
			dfs(i,f);			
		}
	}
}
int main(){
	int n,m,count=0;
	cin>>n>>m;
	while(m--){
		int a,b;
		cin>>a>>b;
		g[a].push_back(b);
	}
	for(int i=1;i<=n;++i){
		memset(vis,false,sizeof(vis));
		vis[i]=true;
		dfs(i,i);
	}
	for(int i=1;i<=n;++i){
		int j;
		for(j=1;j<=n;++j){
			if(!know[i][j]){
				break;
			}
		}
		if(j==n+1){
			count++;
		}
	}
	cout<<count;
	return 0;
}

201712-4 行车路线(Dijkstra)

#include<bits/stdc++.h>
using namespace std;
int n,m;
typedef long long ll;
ll INF=0x3f3f3f3f3f3f3f3f;
const int N=505;

bool vis[N];
ll dist[N];
ll sum[N];
struct Road{
	int t,v;
	ll c;
	Road(int tt,int vv,ll cc){
		t=tt;v=vv;c=cc;
	}
};
struct Node{
	int u;
	ll w;
	Node(int uu,ll ww){
		u=uu;w=ww;
	}
	bool operator <(const Node &n)const{
		return w>n.w;
	}
};
vector<Road> g[N];
void dijkstra(){
	priority_queue<Node> q;
	memset(vis,false,sizeof(vis));
	memset(sum,0,sizeof(sum));
	memset(dist,0x3f,sizeof(dist));
	dist[1]=0;
	q.push(Node(1,0));
	while(!q.empty()){
		Node e=q.top();
		q.pop();
		int u=e.u;
		if(u==n)	break;
		if(!vis[u]){
			vis[u]=true;
			for(Road i:g[u]){
				int v=i.v;
				if(vis[v]){
					continue;
				}
				ll cost=0;
				ll temp=0;
				if(i.t){
					temp=sum[u]+i.c;
					cost=dist[u]-sum[u]*sum[u]+temp*temp;
				}
				else{
					cost=dist[u]+i.c;
				}
				if(cost<dist[v]){
					dist[v]=cost;
					if(i.t){
						sum[v]=temp;
					}
					else
						sum[v]=0;
					q.push(Node(v,cost));
				}
			}
		}
	}
}
int main(){
	freopen("in.txt","r",stdin);
	int n,m;
	cin>>n>>m;
	while(m--){
		int t,a,b,c;
		cin>>t>>a>>b>>c;
		g[a].push_back(Road(t,b,c));
		g[b].push_back(Road(t,a,c));
	}
	dijkstra();
	cout<<dist[n];
	return 0;
}

201803-4 棋局评估(博弈DFS)

#include<bits/stdc++.h>
using namespace std;
int T;
int g[3][3];
int judge(){
	for(int i=0;i<3;++i){
		if(g[i][0]&&g[i][0]==g[i][1]&&g[i][1]==g[i][2]) return g[i][0];
		if(g[0][i]&&g[0][i]==g[1][i]&&g[1][i]==g[2][i]) return g[0][i];	
	} 
	if(g[0][0]&&g[0][0]==g[1][1]&&g[1][1]==g[2][2]) return g[0][0];
	if(g[0][2]&&g[0][2]==g[1][1]&&g[1][1]==g[2][0]) return g[0][2];
	return 0;
}
int dfs(int k){
	int cnt=0,win=judge();
	for(int i=0;i<3;++i)
		for(int j=0;j<3;++j){
			if(!g[i][j]) cnt++; 
		}
	if(win==1) return cnt+1;
	if(win==2) return -cnt-1;
	if(!cnt) return 0;
	
	int maxn=-10,minn=10;
	for(int i=0;i<3;++i){
		for(int j=0;j<3;++j){
			if(!g[i][j]){
				g[i][j]=k;
				if(k==1){
					maxn=max(maxn,dfs(2));
				}
				if(k==2){
					minn=min(minn,dfs(1));
				}
				g[i][j]=0;
			}
		}
	}
	if(k==1){
		return maxn;
	} 
	if(k==2) {
		return minn;
	}
}
int main(){
	freopen("in.txt","r",stdin);
	cin>>T;
	while(T--){
		for(int i=0;i<3;++i){
			for(int j=0;j<3;++j){
				cin>>g[i][j];
			}
		}
		cout<<dfs(1)<<endl;
	}
	return 0;
}

201809-4 再卖菜(差分约束spfa+链式前向星)

//差分约束
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int N=300+10;
const int M=2000+10;
struct Edge
{
    int to,w,nxt;
}edge[M];
int tot,first[N];
void addedge(int u,int v,int w)
{
    edge[tot].to=v;
    edge[tot].w=w;
    edge[tot].nxt=first[u];
    first[u]=tot++;
}
void init()
{
    tot=0;
    memset(first,-1,sizeof(first));
}
int dist[N];
bool vis[N];
void spfa(int n)
{
    queue<int> q;
    for(int i=0;i<=n;i++)
    {
 //       q.push(i);
        vis[i]=false;
        dist[i]=0;
    }
    vis[0]=true;
    q.push(0);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=false;
        for(int i=first[u];i!=-1;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(dist[v]<dist[u]+edge[i].w)
            {
                dist[v]=dist[u]+edge[i].w;
                if(!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
    }
}
int a[N];
int main()
{
	freopen("in.txt","r",stdin);
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    init();
    
    addedge(0,2,2*a[1]);
    addedge(2,0,-2*a[1]-1);
    for(int i=2;i<n;i++)
    {
        addedge(i-2,i+1,3*a[i]);
        addedge(i+1,i-2,-3*a[i]-2);
    }
    addedge(n-2,n,2*a[n]);
    addedge(n,n-2,-2*a[n]-1);
    
    for(int i=1;i<=n;i++)
        addedge(i-1,i,1);
    spfa(n);
    for(int i=1;i<=n;i++)
        a[i]=dist[i]-dist[i-1];
    for(int i=1;i<n;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n]);
    return 0;
}

201812-4 数据中心(Kruskal)

#include<bits/stdc++.h>
using namespace std;
const int N=500005;
struct Edge{
	int u,v,t;
	Edge(){
	}
	Edge(int _u,int _v,int _t){
		u=_u;
		v=_v;
		t=_t;
	}
	bool operator <(const Edge&e)const{
		return t<e.t;
	}
};
int father[N];
int findFather(int x){
	if(father[x]==x) return x;
	int temp=findFather(father[x]);
	father[x]=temp;
	return temp;
}
int ans,tm;
int main(){
	freopen("in.txt","r",stdin);
	int n,m,root;
	cin>>n>>m>>root;
	iota(father,father+n+1,0);
	Edge edges[m];
	for(int i=0;i<m;i++){
		int v,u,t;
		cin>>v>>u>>t;
		edges[i]=Edge(v,u,t);
	}
	sort(edges,edges+m);
	int count=0;
	for(int i=0;i<m;++i){
		int ua=findFather(edges[i].u);
		int ub=findFather(edges[i].v);
		if(ua!=ub){
			father[ua]=ub;
			count++;
		}
		if(count==n-1){
			ans=edges[i].t;
			break;
		}
	}
	cout<<ans;
	return 0;
}

201903-4 消息传递接口(模拟)

#include<bits/stdc++.h>
using namespace std;
const int N=10005;
const int INF=0x3f3f3f3f;
int T,n;
struct Order{
	char type;
	int num;
};
queue<Order> orders[N];
int stoNum(const string &s){
	int ans=0;
	for(auto c:s){
		ans=ans*10+c-'0';
	}
	return ans;
}
int main(){
//	ios::sync_with_stdio(false);
//	cin.tie(0);
//	cout.tie(0);
	freopen("in.txt","r",stdin);
	cin>>T>>n;
	getchar();//用了上面注释的代码导致getchar()无法从缓冲区读,要用下面的方式 
//	cin.get();
	while(T--){
		for(int i=0;i<n;++i){
			string s;
			getline(cin,s);
			stringstream ss(s);
			string str;
			while(ss>>str){
				orders[i].push({str[0],stoNum(str.substr(1))});
			}
		}
		bool flag=true;
		while(flag){
			flag=false;
			for(int i=0;i<n;++i){
				if(orders[i].empty()) continue;
				Order top=orders[i].front();
				
				if(!orders[top.num].empty()){
					Order top1=orders[top.num].front();
					if(top1.num==i&&(((top1.type+top.type)=='R'+'S')||((top1.type+top.type)=='S'+'R'))){
						orders[i].pop();
						orders[top.num].pop();
						flag=true;
					}
				}
			}
		}
		int dead=false;
		for(int k=0;k<n;++k){
			if(!orders[k].empty())
				dead=true;
			orders[k]=queue<Order>();
		}
		cout<<dead<<endl;
		
	}
	return 0;
}

201909-4 推荐系统(模拟)

#include<bits/stdc++.h>
using namespace std;
struct Commodity{
	long long id,score;
	Commodity(long long _id,long long _score):id(_id),score(_score){}
	bool operator<(const Commodity &c)const{
		if(score==c.score){
			return id<c.id;
		}else{
			return score>c.score;
		}
	}
};
int main() {
	freopen("in.txt","r",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	const long long mul=(long long)(1e9);
	int m,n,id,score,op,t,c,k;
	cin>>m>>n;
	vector<int> K(m);
	set<Commodity> commodities;
	unordered_map<long long,set<Commodity>::iterator> um;
	for(int i=0;i<n;++i){
		cin>>id>>score;
		for(int j=0;j<m;++j){
			long long a=j*mul+id;
			um[a]=commodities.insert(Commodity(a,score)).first;
		}
	}
	cin>>op;
	while(op--){
		cin>>c;
		if(c==1){
			cin>>t>>id>>score;
			long long a=t*mul+id;
			um[a]=commodities.insert(Commodity(a,score)).first;
		}
		else if(c==2){
			cin>>t>>id;
			long long a=t*mul+id;
			commodities.erase(um[a]);
			um.erase(a);
		}else{
			vector<vector<int>> ans(m);
			cin>>k;
			for(int i=0;i<m;++i){
				cin>>K[i];
			}
			for(auto &i:commodities){
				t=i.id/mul;
				if(ans[t].size()<K[t]){
					ans[t].push_back(i.id%mul);
					k--;
					if(k==0) break;
				}
			}
			for(auto &i:ans){
				if(i.empty()){
					cout<<"-1\n";
				}else{
					for(auto j:i){
						cout<<j<<" ";
					}
					cout<<endl;
				}
			}
		}
	}
	return 0;
}

201912-4 区块链(模拟|bfs)

#include<bits/stdc++.h>
using namespace std;
const int N=505;
int n,m,k,t;
vector<int> g[N];
vector<int> ans[N];
map<int,unordered_map<int,array<vector<int>,2>>> actions;

bool canAccept(const vector<int> &Old,const vector<int> &New){
	return Old.size()!=New.size()?Old.size()<New.size():Old.back()>New.back();
}

void diffuse(int v,int time){
	for(int i:g[v]){
		auto &chain=actions[time][i][0];
		if((chain.empty()&&canAccept(ans[i],ans[v]))||(!chain.empty()&&canAccept(chain,ans[v]))){
			chain=ans[v];
		}
	}
}

void query(int a,int b){
	for(auto &action:actions){
		int curTime=action.first;
		if(curTime>b) break;
		for(auto &vertex:action.second){
			int v=vertex.first;
			auto &chain=vertex.second[0];
			auto &blocks=vertex.second[1];
			bool canDiffuse=canAccept(ans[v],chain)||!blocks.empty();
			if(canAccept(ans[v],chain)){
				ans[v]=chain;
			}
			for(int b:blocks){
				ans[v].push_back(b);
			}
			if(canDiffuse){
				diffuse(v,curTime+t);
			}
		}
	}
	actions.erase(actions.begin(),actions.upper_bound(b));
	cout<<ans[a].size();
	for(int i:ans[a]){
		cout<<' '<<i;
	}
	cout<<endl;
}

int main(){
	freopen("in.txt","r",stdin);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;++i){
		ans[i].push_back(0);
	} 
	for(int i=1;i<=m;++i){
		int u,v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	cin>>t>>k;
	for(int i=1;i<=k;++i){
		int a,b,c;
		cin>>a>>b;
		if(cin.get()=='\n'||cin.eof()){
			query(a,b);
		}
		else{
			cin>>c;
			actions[b][a][1].push_back(c);
		}
	}
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
struct Node{
	int time;
	int u;
	vector<int>vec;
};
queue<Node>que;
vector<vector<int>>gra(505, vector<int>());
vector<vector<int>>block(505, vector<int>());
void toNum(string s, vector<int>& res){
	res.clear();
	int num = 0;
	for(int i = 0; i < s.size(); ++i){
		if(isdigit(s[i])){
			num = num * 10 + s[i] - '0';
		}
		else{
			res.push_back(num);
			num = 0;
		}
	}
	if(num != 0)
		res.push_back(num);
}
int main(){
	freopen("in.txt", "r", stdin);
	int n, m, t, k;
	int u, v, a, b, c;
	string s;
	vector<int>res;
	while(!que.empty()){
		que.pop();
	}
	gra.clear();
	block.clear();
	for(int i = 0; i < 505; ++i){
		block[i].push_back(0);
	}
	scanf("%d%d",&n, &m);
	for(int i = 0; i < m; ++i){
		scanf("%d%d", &u, &v);
		gra[u].push_back(v);
		gra[v].push_back(u);
	}
	scanf("%d%d", &t, &k);
	getchar();
	for(int i = 0; i < k; ++i){
		getline(cin, s);
		toNum(s, res);
		while(!que.empty()){
			Node frt = que.front();
			if(frt.time <= res[1]){
				que.pop();
				int u = frt.u, v;
				for(int i = 0; i < gra[u].size(); ++i){
					v = gra[u][i];
					if(block[v].size() < frt.vec.size()){
						block[v] = frt.vec;
						Node tmp;
						tmp.time = frt.time + t;
						tmp.u = v;
						tmp.vec = block[v];
						que.push(tmp);
					}
					else if(block[v].size() == frt.vec.size()){
						if(block[v].back() > frt.vec.back()){
							block[v] = frt.vec;
							Node tmp;
							tmp.time = frt.time + t;
							tmp.u = v;
							tmp.vec = block[v];
							que.push(tmp);
						}
					}
				}
			}
			else{
				break;
			}
		}
		
		if(res.size() == 3){//update
			block[res[0]].push_back(res[2]);
			Node tmp;
			tmp.time = res[1] + t;
			tmp.u = res[0];
			tmp.vec = block[res[0]];
			que.push(tmp);
		}
		else{
			int u = res[0];
			printf("%d", block[u].size());
			for(int i = 0; i < block[u].size(); ++i){
				printf(" %d", block[u][i]);
			}
			printf("\n");
		}
	}
	return 0;
}

202009-4 星际旅行(模拟)

#include<bits/stdc++.h>
using namespace std;
const int N=105;
const int M=2005;

int n,m,r;
int point[M][N];
double dis[M][M];
double ans;
long long dirdis2[M][M];
long long PO2[M];

bool isOut(int x,int y){
	double a=sqrt(PO2[x]);
	double b=sqrt(PO2[y]);
	double c=sqrt(dirdis2[x][y]);
	double p=(a+b+c)/2;
	double S=sqrt(p*(p-a)*(p-b)*(p-c));
	
	double h=2*S/c;
	
	if(h>=r) return 1;
	else if(c*c+a*a<b*b) return 1;
	else if(c*c+b*b<a*a) return 1;
	else return 0;
}

long long caldirdis(int x,int y){
	long long ans=0;
	for(int i=1;i<=n;++i){
		ans+=(point[x][i]-point[y][i])*(point[x][i]-point[y][i]);
	}
	return ans;
}

double caltheta(int x,int y){
	double a=sqrt(PO2[x]);
	double b=sqrt(PO2[y]);
	double c=sqrt(dirdis2[x][y]);
	return acos((a*a+b*b-c*c)/(2*a*b));
}

double calcirdis(int x,int y){
	double a2=PO2[x];
	double b2=PO2[y];
	
	double part1=caltheta(x,y)*r-acos(sqrt(r*r/a2))*r-acos(sqrt(r*r/b2))*r;
	double part2=sqrt(a2-r*r);
	double part3=sqrt(b2-r*r);
	return part1+part2+part3;
}

void caldis(int x,int y){
	dirdis2[x][y]=caldirdis(x,y);
	dirdis2[y][x]=dirdis2[x][y];
	if(isOut(x,y)){
		dis[x][y]=sqrt(dirdis2[x][y]);
		dis[y][x]=dis[x][y];
	}
	else{
		dis[x][y]=calcirdis(x,y);
		dis[y][x]=dis[x][y];
	}
}

int main(){
	freopen("in.txt","r",stdin);
	cin>>n>>m>>r;
	for(int i=1;i<=n;++i){
		cin>>point[0][i];
	}
	for(int j=1;j<=m;++j){
		for(int i=1;i<=n;++i){
			cin>>point[j][i];
			PO2[j]+=(point[j][i]-point[0][i])*(point[j][i]-point[0][i]);
		}
	}
	for(int i=1;i<=m;++i){
		for(int j=i+1;j<=m;++j){
			caldis(i,j);
		}
	}
	for(int i=1;i<=m;++i){
		ans=0;
		for(int j=1;j<=m;++j){
			ans+=dis[i][j];
		}
		printf("%.14lf\n",ans);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值