日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

20170824图论选讲部分习题

發(fā)布時(shí)間:2025/3/21 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 20170824图论选讲部分习题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.車站分級(jí)

講過(guò)啊,拓?fù)渑判?#xff0c;每個(gè)??康能囌鞠蛩形赐?康能囌具B一條邊,拓?fù)鋵訑?shù)即可,小優(yōu)化,每次刪0度點(diǎn)的邊時(shí)順便統(tǒng)計(jì)一下刪好后為0度點(diǎn)的邊

#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define maxn 1005 using namespace std; int to[maxn][maxn],point[maxn],Map[maxn][maxn],x[maxn],v[maxn],a[maxn],b[maxn]; int ans=0,n,m; void work() {for(int i=1;i<=n;i++)if(!v[i]) point[++point[0]]=i;while(point[0]){ans++;while(point[0]){int k=point[point[0]];point[0]--;for(int i=1;i<=to[k][0];i++){v[to[k][i]]--;if(!v[to[k][i]]) x[++x[0]]=to[k][i];}}for(int i=1;i<=x[0];i++)point[i]=x[i];point[0]=x[0];x[0]=0;}printf("%d\n",ans); } int main() {scanf("%d %d",&n,&m);for(int i=1;i<=m;i++){scanf("%d",&a[0]);b[0]=0;for(int i=1;i<=a[0];i++) scanf("%d",&a[i]);for(int i=1;i<a[0];i++)for(int j=a[i]+1;j<a[i+1];j++)b[++b[0]]=j;for(int i=1;i<=a[0];i++)for(int j=1;j<=b[0];j++)if(!Map[a[i]][b[j]]){Map[a[i]][b[j]]=1;v[b[j]]++;to[a[i]][++to[a[i]][0]]=b[j];} }work(); }

2.種樹,這個(gè)我寫過(guò)題解了

3.秦始皇的國(guó)家道路。先枚舉選的是那條邊,因?yàn)閏nt總值最小肯定更優(yōu),我們用Prim求最小生成樹可以接近最優(yōu)值,考慮到加上選的邊后的最小生成樹是由原最小生成樹換1條邊的正確性可由Kruskal來(lái)證明吧。就是把最小生成樹中u,v中的那條路徑中最大的一條邊換成枚舉的那條邊。

#include<cstdio> #include<cmath> #include<algorithm> using namespace std; struct node{ int x,y; double val; }a[2000005]; int num1,num,f1,root; int f[2000005],p[2000005],flag[2000005]; double dis[1005][1005],x[2000005],y[2000005]; int v[2000005],next[2000005],head[10005],vis[10005]; double v1[2000005]; int find(int u) { if (f[u]!=u) f[u]=find(f[u]); return f[u]; } void add(int a,int b,double val) { num1++; v[num1]=b; v1[num1]=val; next[num1]=head[a]; head[a]=num1; } bool cmp(node a,node b) { return a.val<b.val; } void dfs(int u,double val) { dis[root][u]=val; vis[u]=f1; for (int i=head[u]; i; i=next[i]) { int V=v[i]; if (vis[V]!=f1) dfs(V,max(val,v1[i])); } } int main() { int asdasdasdasd;int t; scanf("%d",&t); while (t--) { num1=0; num=0; int n; scanf("%d",&n); for (int i=1; i<=n; i++) head[i]=0; for (int i=1; i<=n; i++) scanf("%lf%lf%d",&x[i],&y[i],&p[i]); for (int i=1; i<=n; i++) for (int j=i+1; j<=n; j++) { double dis=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]); num++; a[num].x=i; a[num].y=j; a[num].val=sqrt(dis); /*num++; a[num].x=j; a[num].y=i; a[num].val=sqrt(dis);*/} sort(a+1,a+num+1,cmp); for (int i=1; i<=n; i++) f[i]=i; double ans=0; for (int i=1; i<=num; i++) { flag[i]=0; int fx=find(a[i].x); int fy=find(a[i].y); if (fx!=fy) { f[fx]=fy; //f[fx]=find(fx); ans+=a[i].val; flag[i]=1; } } for (int i=1; i<=num; i++) if (flag[i]) { add(a[i].x,a[i].y,a[i].val); add(a[i].y,a[i].x,a[i].val); } f1=0; for (int i=1; i<=n; i++) { f1++; root=i; dfs(i,0); } double ans1=0; for (int i=1; i<=n; i++) for (int j=i+1; j<=n; j++) if ((p[i]+p[j])/(ans-dis[i][j])>ans1) ans1=(p[i]+p[j])/(ans-dis[i][j]); printf("%.2f\n",ans1); } return 0; }

4.受歡迎的奶牛

Tarjan求強(qiáng)連通分量縮點(diǎn)

求度為0的個(gè)數(shù),如果大于等于2個(gè),無(wú)解,不然輸出度為0的強(qiáng)連通分量的size

#include<iostream> #include<cstdio> #include<algorithm> #include<stack> #define maxn 100100 using namespace std; stack<int> S; struct note{int u,v; }edge[maxn]; bool instack[maxn]; int to[maxn*2],id[maxn],Time,ans,num,sc,head[maxn],visit[maxn],next[maxn*2],low[maxn],dfn[maxn],n,m,size[maxn]; void make_way(int u,int v) {to[++num]=v;next[num]=head[u];head[u]=num; } void tarjan(int u,int fa) {dfn[u]=low[u]=++Time;instack[u]=1;S.push(u);for(int ed=head[u];ed;ed=next[ed]){if(!dfn[to[ed]]){tarjan(to[ed],u);low[u]=min(low[u],low[to[ed]]);}elseif(instack[to[ed]])low[u]=min(low[u],dfn[to[ed]]);}//cout<<u<<' '<<low[u]<<' '<<dfn[u]<<endl;if(low[u]==dfn[u]){sc++;int v;do{v=S.top();S.pop();instack[v]=0;id[v]=sc;size[sc]++; }while(v!=u&&!S.empty());} } int main() {scanf("%d %d",&n,&m);for(int i=1;i<=m;i++){scanf("%d %d",&edge[i].u,&edge[i].v);make_way(edge[i].u,edge[i].v);}for(int i=1;i<=n;i++)if(!dfn[i]){tarjan(i,0);}for(int i=1;i<=m;i++)if(id[edge[i].u]!=id[edge[i].v])visit[id[edge[i].u]]++;bool flag=0;for(int i=1;i<=sc;i++){if(!visit[i]){if(flag){ cout<<0<<endl;return 0;}flag=1;ans=i;}}printf("%d\n",size[ans]);}

6.礦場(chǎng)搭建

WA10分,待改

#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define ll long long using namespace std; int n,m,cnt,num,tot,son_num,ans1,Time,T,cases,root; ll ans2; int head[500005],dfn[500500],low[500005],vis[500005]; bool cut[500005]; int Next[1000005],to[1000005]; void make_way(int u,int v) {to[++num]=v;Next[num]=head[u];head[u]=num;} void tarjan(int u,int fa_edge){low[u]=dfn[u]=++Time;for(int edge=head[u];edge;edge=Next[edge])if(edge^1!=fa_edge){int v=to[edge];if(!dfn[v]){tarjan(v,u);low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]){if(u==root) son_num++;else cut[u]=1;}}else{low[u]=min(low[u],dfn[v]);} }}void dfs(int u){vis[u]=T;if(cut[u]) return;cnt++;for(int edge=head[u];edge;edge=Next[edge]){if(cut[to[edge]]&&vis[to[edge]]!=T) num++,vis[to[edge]]=T;if(!vis[to[edge]]) dfs(to[edge]);}} int main() {int Case=0;while(~scanf("%d",&m)&&m){Case++;memset(head,0,sizeof(head));memset(dfn,0,sizeof(dfn));memset(vis,0,sizeof(vis));memset(low,0,sizeof(low));memset(cut,0,sizeof(cut));Time=num=n=ans1=T=0;for(int i=1;i<=m;i++){int u,v;scanf("%d %d",&u,&v);n=max(n,max(u,v));make_way(u,v);make_way(v,u);}for(int i=1;i<=n;i++){if(!dfn[i])tarjan(root=i,0);if(son_num>=2)cut[root]=1;son_num=0;}ans1=0;ans2=1;for(int i=1;i<=n;i++)if(!vis[i]&&!cut[i]){T++;cnt=num=0;dfs(i);if(!num) ans1+=2,ans2*=cnt*(cnt-1)/2;if(num==1) ans1++,ans2*=cnt;}printf("Case %d: %d %lld\n",Case,ans1,ans2);}}

?

轉(zhuǎn)載于:https://www.cnblogs.com/dancer16/p/7436589.html

總結(jié)

以上是生活随笔為你收集整理的20170824图论选讲部分习题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。