标签:sort 匈牙利 解决 nic 匈牙利算法 cstring dfs memcpy bfs
T1:
倍增处理x到y是否能通过2i的引导力到达。如果可以,则连由x向y的边。
而后对连边从s到做bfs即可。注意判断无解的情况。
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define LG 35 5 #define MN 53 6 using namespace std; 7 inline int in(){ 8 int x=0;bool f=0; char c; 9 for (;(c=getchar())<‘0‘||c>‘9‘;f=c==‘-‘); 10 for (x=c-‘0‘;(c=getchar())>=‘0‘&&c<=‘9‘;x=(x<<3)+(x<<1)+c-‘0‘); 11 return f?-x:x; 12 } 13 bool vis[LG][MN][MN],mk; 14 int dis[MN],q[MN<<1]; 15 int n,m,p,s,t,x,y,head,tail; 16 inline void floyd(){ 17 for (int l=2;l<=p;++l) 18 for (int k=1;k<=n;++k) 19 for (int i=1;i<=n;++i) 20 for (int j=1;j<=n;++j) vis[l][i][j]|=(vis[l-1][i][k]&&vis[l-1][k][j]); 21 } 22 int main() 23 { 24 n=in();m=in();p=in();s=in();t=in(); 25 for (int i=1;i<=m;++i){ 26 x=in();y=in();vis[1][y][x]=1; 27 }floyd();head=tail=1;q[1]=s;dis[s]=1; 28 while (head<=tail){ 29 int u=q[head];++head;if (u==t){mk=1;break;} 30 for (int v=1;v<=n;++v)if (!dis[v]){ 31 for (int j=1;j<=p;++j) 32 if (vis[j][u][v]) {dis[v]=dis[u]+1;q[++tail]=v;break;} 33 } 34 }printf("%d",mk?dis[t]-1:-1);return 0; 35 }
T2:考虑能使主对角线均为黑格时,可以从每行恰好取一个黑格,使得黑格遍历所有列。
考虑对行与列进行匹配,行向列连边,转化为二分图匹配问题。使用匈牙利算法或网络流解决。
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 #define clr(x) memset(x,0,sizeof(x)) 6 #define inf 0x7fffffff 7 #define ME 100005 8 #define MN 405 9 using namespace std; 10 inline int in(){ 11 int x=0;bool f=0; char c; 12 for (;(c=getchar())<‘0‘||c>‘9‘;f=c==‘-‘); 13 for (x=c-‘0‘;(c=getchar())>=‘0‘&&c<=‘9‘;x=(x<<3)+(x<<1)+c-‘0‘); 14 return f?-x:x; 15 } 16 struct edge{ 17 int to,next,cap; 18 }e[ME]; 19 int head[MN],iter[MN],lev[MN]; 20 int T,n,cnt=1,s,t,a; 21 inline void ins(int x,int y,int cp){ 22 e[++cnt].to=y;e[cnt].next=head[x];head[x]=cnt;e[cnt].cap=cp; 23 e[++cnt].to=x;e[cnt].next=head[y];head[y]=cnt;e[cnt].cap=0; 24 } 25 inline void bfs(){ 26 queue<int>q;memset(lev,-1,sizeof(lev)); 27 q.push(s);lev[s]=0; 28 while (!q.empty()){ 29 int u=q.front();q.pop(); 30 for (int i=head[u];i;i=e[i].next){ 31 int v=e[i].to; 32 if (lev[v]==-1&&e[i].cap>0) 33 lev[v]=lev[u]+1,q.push(v); 34 } 35 } 36 } 37 inline int dfs(int u,int f){ 38 if (u==t) return f;int used=0; 39 for (int &i=iter[u];i;i=e[i].next){ 40 int v=e[i].to; 41 if (lev[u]<lev[v]&&e[i].cap>0){ 42 int w=dfs(v,min(f-used,e[i].cap)); 43 if (w>0){ 44 e[i].cap-=w;e[i^1].cap+=w;used+=w; 45 if (f==used) return f; 46 } 47 } 48 }return used; 49 } 50 inline int dinic(){ 51 int fl=0;while (1){ 52 bfs();if (lev[t]==-1) return fl; 53 memcpy(iter,head,sizeof(head)); 54 int d=0;while ((d=dfs(s,inf))>0) fl+=d; 55 } 56 } 57 inline void init(){ 58 clr(lev);clr(head);clr(iter); 59 clr(e);s=t=0;cnt=1; 60 } 61 int main() 62 { 63 T=in();while (T--){ 64 n=in();init();s=(n<<1)+1;t=(n<<1)+2; 65 for (int i=1;i<=n;++i) 66 for (int j=1;j<=n;++j){ 67 a=in();if (a) ins(i,j+n,inf); 68 }for (int i=1;i<=n;++i) ins(s,i,1),ins(i+n,t,1); 69 puts((dinic()==n)?"Yes":"No"); 70 }return 0; 71 }
T3:考虑dp.
离散每个点。可以发现,当两点x,y间距离大于值z时,当gcd(di)|y时,x 总能转移到x+y。实际上,z 可能的最大值为7*8=56。
求出所有d的gcd,不计算不是gcd的倍数的格子,对距离较远的宝石进行距离上的压缩。
如果它们之间的距离大于z,把距离压到z 值附近。dp即可。
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define ll long long 5 #define inf 0x7f7f7f7f7f7f7f7fll 6 #define MN 100005 7 #define MM 11000005 8 using namespace std; 9 inline ll in(){ 10 ll x=0;bool f=0; char c; 11 for (;(c=getchar())<‘0‘||c>‘9‘;f=c==‘-‘); 12 for (x=c-‘0‘;(c=getchar())>=‘0‘&&c<=‘9‘;x=(x<<3)+(x<<1)+c-‘0‘); 13 return f?-x:x; 14 } 15 struct st{ 16 ll p,w; 17 }a[MN]; 18 ll pos[MN],mx[MN],f[MM],wt[MN],val[MM]; 19 bool vis[60]; 20 ll d[10],n,m,k,cnt,top,mc,md,mt,dv,ct,cur,res; 21 inline bool cmp(st x,st y){return x.p<y.p;} 22 inline int gcd(int x,int y){return y?gcd(y,x%y):x;} 23 int main() 24 { 25 freopen("tomato.in","r",stdin); 26 freopen("tomato.out","w",stdout); 27 n=in();m=in();k=in(); 28 for (int i=1;i<=k;++i) d[i]=in(),dv*=d[i]; 29 for (int i=1;i<=k;++i) dv=gcd(dv,d[i]); 30 for (int i=1;i<=m;++i) a[i].p=in(),a[i].w=in(); 31 a[++m].p=0;a[m].w=0;sort(a+1,a+m+1,cmp);pos[0]=-1; 32 for (int i=1;i<=m;++i){ 33 if (a[i].p%dv) continue; 34 if (a[i].p/dv==pos[cnt]) wt[cnt]+=a[i].w; 35 else pos[++cnt]=a[i].p/dv,wt[cnt]=a[i].w; 36 }mc=inf;vis[0]=1;mt=-1; 37 for (int i=1;i<=k;++i) d[i]/=dv,mc=min(mc,d[i]); 38 for (md=0;;++md){ 39 for (int j=1;j<=k;++j) 40 if (md>=d[j]) vis[md]|=vis[md-d[j]]; 41 if (!vis[md]) mt=md;if (md-mt==mc) break; 42 }for (int i=1;i<=k;++i) md=max(md,d[i]+1); 43 md+=8;val[0]=wt[1];cur=0; 44 for (int i=2;i<=cnt;++i){ 45 if (pos[i]-pos[i-1]>md) cur+=md+1; 46 else cur+=pos[i]-pos[i-1];val[cur]=wt[i]; 47 }memset(f,0x80,sizeof(f));res=f[0]=val[0]; 48 for (int i=1;i<=cur;++i){ 49 for (int j=1;j<=k;++j) 50 if (d[j]<=i)f[i]=max(f[i],f[i-d[j]]+val[i]); 51 res=max(res,f[i]); 52 }printf("%lld",res);return 0; 53 }
标签:sort 匈牙利 解决 nic 匈牙利算法 cstring dfs memcpy bfs
原文地址:http://www.cnblogs.com/codingutopia/p/test171101.html