Codeforces Round #257 (Div. 2)
前三题特水~~~~
第四题,迪杰斯特拉算法。只需在裸的算法改点东西就行
#include<cstdio> #include<cstring> #include<vector> #include<queue> #define maxn 100005 #define inf 1<<30 using namespace std; int route[maxn]; int cnt[maxn]; struct edge { int from,to,dist; bool flag; }; struct node { int d,u; bool operator<(const node &t)const { return d>t.d; } }; struct Di { int n,m,ans; vector<edge>ed; vector<int>g[maxn]; bool done[maxn]; int d[maxn]; int p[maxn]; bool biao[maxn]; void init(int n) { ans=0; this->n=n; for(int i=0; i<n; i++) { g[i].clear(); biao[i]=0; } ed.clear(); } void addedge(int from,int to,int dis,bool flag) { ed.push_back((edge) { from,to,dis,flag }); m=ed.size(); g[from].push_back(m-1); } void dijkstra() { priority_queue<node>q; for(int i=0; i<n; i++) d[i]=inf; d[0]=0; memset(done,0,sizeof done); q.push((node) { 0,0 }); while(!q.empty()) { node x=q.top(); q.pop(); int u=x.u; if(done[u])continue; done[u]=1; for(int i=0; i<g[u].size(); i++) { edge& e=ed[g[u][i]]; if(d[e.to]>d[u]+e.dist) { if(e.flag) biao[e.to]=1; if(e.flag==0&&biao[e.to]) { ans++; biao[e.to]=0; } d[e.to]=d[u]+e.dist; p[e.to]=g[u][i]; q.push(node {d[e.to],e.to}); } else if(d[e.to]==d[u]+e.dist) { if(e.flag==0&&biao[e.to]) { ans++; biao[e.to]=0; } if(e.flag) ans++; } else if(e.flag) {ans++;} } } } }; Di solve; int main() { int n,m,k,x,y,d; scanf("%d",&n); solve.init(n); scanf("%d%d",&m,&k); for(int i=0; i<m; i++) { scanf("%d%d%d",&x,&y,&d); x--; y--; solve.addedge(x,y,d,0); solve.addedge(y,x,d,0); } for(int i=1; i<n; i++) route[i]=-1; for(int i=0; i<k; i++) { scanf("%d%d",&x,&d); x--; if(route[x]>=0) { route[x]=min(route[x],d); solve.ans++; } else route[x]=d; } for(int i=1; i<n; i++) { if(route[i]>=0) solve.addedge(0,i,route[i],1); } solve.dijkstra(); printf("%d\n",solve.ans); return 0; }
第五题;
一开始没有想到,看了官方题解之后焕然大悟,就是应该那样做的
#include<cstdio> #include<cstring> #include<vector> #define maxn 100005 using namespace std; bool prim[maxn]; bool vis[maxn]; int last[maxn]; vector<int>ve[2]; vector<int>tmp; int main() { int n; scanf("%d",&n); int cot=0; for(int i=2; i<=n/2; i++) { if(!prim[i]) { for(int j=2*i; j<=n; j+=i) prim[j]=1; } } for(int i=n/2; i>=2; i--) { if(!prim[i]) { tmp.clear(); for(int j=1; j*i<=n; j++) { if(vis[j*i])continue; if(j!=2) { tmp.push_back(j*i); vis[j*i]=1; } } if((tmp.size())&1) { tmp.push_back(2*i); vis[2*i]=1; } for(int j=0;j<tmp.size();j+=2) { ve[0].push_back(tmp[j]); ve[1].push_back(tmp[j+1]); } } } printf("%d\n",ve[0].size()); for(int i=0;i<ve[0].size();i++) printf("%d %d\n",ve[0][i],ve[1][i]); return 0; }